我使用Macintosh .tiff
扫描了一张图片(millions of colors
),这意味着24 bits per pixel
。我获得的扫描图像具有以下属性:size = 330KB
和维度= 348 * 580 pixels
。由于每像素有24位,因此大小实际应为348 * 580 * 3 = 605KB
。
有什么不正确的吗?我还使用此代码从扫描图像的URL中提取图像原始数据:
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);
从这段代码中,我得到的信息与图像中每个像素的宽度,高度和位数相同。
基本上,我必须使用此图像的信息并以其他形式将其复制到其他位置,因此如果我无法获得正确的信息,则最终产品不可重现。这可能有什么问题?
P.S。:如果需要一些其他信息来回答这个问题,那么我很乐意提供这个。
答案 0 :(得分:1)
最常见的图片格式jpg
,png
和tiff
压缩图片,这就是文件大小低于每个像素w*h*bits
的原因。
JPEG使用有损压缩,PNG使用无损压缩,TIFF可以解压缩,使用有损压缩或无损压缩。
有损压缩意味着压缩过程中会丢失一些颜色信息,因此图像看起来与压缩前的图像不完全相同,但您可以使用有损压缩进一步减小文件大小。
无损压缩的一个例子是run length encoding,这基本上意味着如果你有几个具有相同颜色的连续像素,你只需要说N
像素值为(R,G,B)
而不是说(R,G,B),(R,G,B),...,(R,G,B)
答案 1 :(得分: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可以做到这一切。