0

I scanned an image (.tiff) with Macintosh millions of colors which means 24 bits per pixel. The scanned image that I am getting has the following attributes: size = 330KB and dimensions = 348 * 580 pixels. Since, there are 24 bits per pixel, the size should actually be 348 * 580 * 3 = 605KB.

Is there something incorrect? I also used this code to extract the image raw data from the url of the image scanned:

NSString * urlName = [url path];
NSImage *image = [[NSImage alloc] initWithContentsOfFile:urlName];
NSData *imageData = [image TIFFRepresentation];
CGImageSourceRef source = CGImageSourceCreateWithData((CFDataRef)CFBridgingRetain(imageData), NULL);
CGImageRef imageRef =  CGImageSourceCreateImageAtIndex(source, 0, NULL);
NSUInteger numberOfBitsPerPixel = CGImageGetBitsPerPixel(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
NSUInteger width = CGImageGetWidth(imageRef);

From this code also, I am getting the same info about the width, height and number of bits per pixel in the image.

Basically, I have to use this image's information and reproduce it somewhere else in some other form, so if I'll not be able to get the correct the information, the final product is not reproducible. What can be wrong here?

P.S.: If some other information is needed to answer the question, then I'll be happy to provide that.

4

2 回答 2

1

最常见的图像格式jpgpngtiff压缩图像,这就是文件大小低于w*h*bits每像素的原因。

JPEG 使用有损压缩,PNG 使用无损压缩,而 TIFF 可以不压缩,使用有损压缩或无损压缩。

有损压缩意味着在压缩过程中会丢失一些颜色信息,因此图像看起来不会与压缩前完全一样,但您可以使用有损压缩进一步减小文件大小。

无损压缩的一个例子是运行长度编码,这基本上意味着如果你有几个具有相同颜色的连续像素,你只是说你有N像素值(R,G,B)而不是说(R,G,B),(R,G,B),...,(R,G,B)

于 2013-10-03T09:00:43.990 回答
1

几天前,您问了(几乎)相同的问题,但没有得到答案。我没有时间回答你的问题,但现在是时候写一些评论了。

首先,您的问题和(大多数)答案和评论显示出对和存储在文件系统中的图像NSImage的很大误解。NSImageRep

存储在文件系统中的图像是一个复杂的数据结构,它不仅包含图像的所有像素(如果是光栅图像),还包含许多元数据:评论、一些日期、有关相机的信息、缩略图和所有有时会采用不同的格式:exif、photoshop、xml 等。因此,您不能假设文件的大小与计算机中要在屏幕上显示的图像或被要求提供某些特殊属性有关。要获取这些数据以供进一步使用,您可以执行以下操作:

NSData *imgData = [NSData dataWithContentsOfURL:url];

或者

NSData *imgData = [NSData dataWithContentsOfFile:[url path]];

或者您直接将图像加载为 NSImage 的对象:

NSImage *image = [[NSImage alloc] initWithContentsOfURL:url];  // similar methods:see the docs

而且,如果您现在认为这是转换为 Cocoa 结构的文件图像数据,那您就错了。NSImage 类的对象不是图像,它只是零个、一个或多个图像表示的容器。Gif、jpg、png 图像总是只有一种表示,tiff 可能有一个或多个,icns 大约有 5 或 6 个图像表示。

现在我们想要一些关于图像表示的信息:

for( NSUInteger i=0; i<[[image representations] count]; i++ ){
   // let us assume we have an NSBitmapImagedRep
   NSBitmapImageRep *rep = [[image representations] objectAtIndex:i];
   // get informations about this rep
   NSUInteger pixelX = [rep pixelsWide];
   NSUInteger pixelY = [rep pixelsHigh];
   CGFloat sizeX = [rep size].width;
   CGFloat sizeY = [rep size].height;
   CGFloat resolutionX = 72.0*pixelX/sizeX;
   CGFloat resolutionY = 72.0*pixelY/sizeY;

   // test if there are padding bits per pixel
   if( [rep bitsPerSample]>=8 ){
       NSInteger paddingBits = [rep bitsPerPixel] - [rep bitsPerSample]*[rep samplesPerPixel];

   // test if there are padding bytes per row
   NSInteger paddingBytes = [rep bytesPerRow] - ([rep bitsPerPixel]*[rep pixelsWide]+7)/8;

   NSUInteger bitmapSize =  [rep bytesPerRow] * [rep pixelsHigh];
}

另一种说法:你说:

我用 Macintosh 数百万种颜色扫描了一张图像 (.tiff),这意味着每像素 24 位。

不,不必如此。如果一个像素只有三个分量,由于某些优化规则,它可能不仅使用 24 位,有时还使用 32 位。询问代表。它会告诉你真相。并要求使用 bitmsapFormat!(文档中的详细信息)。

最后:您不需要使用 CG 功能。NSImage 和 NSImageRep 做到了这一切。

于 2013-10-03T16:11:12.793 回答