Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 图像大小与尺寸不同_Objective C_Image_Macos_Nsdata_Nsimage - Fatal编程技术网

Objective c 图像大小与尺寸不同

Objective c 图像大小与尺寸不同,objective-c,image,macos,nsdata,nsimage,Objective C,Image,Macos,Nsdata,Nsimage,我用Macintosh数百万种颜色扫描了一幅图像(.tiff),这意味着每像素24位。我得到的扫描图像具有以下属性:size=330KB和dimensions=348*580像素。因为每个像素有24位,所以大小实际上应该是348*580*3=605KB 有什么不对劲吗?我还使用此代码从扫描图像的url中提取图像原始数据: NSString * urlName = [url path]; NSImage *image = [[NSImage alloc] initWithContentsOfFil

我用Macintosh
数百万种颜色扫描了一幅图像(
.tiff
),这意味着
每像素24位。我得到的扫描图像具有以下属性:
size=330KB
和dimensions=
348*580像素
。因为每个像素有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);
从这段代码中,我也得到了关于图像中每个像素的宽度、高度和位数的相同信息

基本上,我必须使用这个图像的信息,并以其他形式在其他地方复制它,因此,如果我无法获得正确的信息,最终产品是不可复制的。这里有什么问题


附言:如果需要一些其他信息来回答这个问题,那么我很乐意提供。

最常见的图像格式
jpg
png
tiff
压缩图像,这就是文件大小低于
w*h*位
每像素的原因

JPEG使用有损压缩,PNG使用无损压缩,TIFF可以解压缩,使用有损压缩或无损压缩

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


无损压缩的一个例子是,这基本上意味着如果你有几个相同颜色的消费像素,你只需说你有
N
个值
(R,G,B)
的像素,而不是说
(R,G,B),(R,G,B),…,(R,G,B)
几天前你问了(几乎)相同的问题,但没有得到答案。我没有时间回答你的问题,但现在是时候写一些评论了

首先,您的所有问题以及(大多数)答案和评论表明,您对
NSImage
NSImageRep
和存储在文件系统中的映像有很大的误解

存储在文件系统中的图像是一个复杂的数据结构,它不仅包含图像的所有像素(如果是光栅图像),而且还包含大量元数据:注释、一些日期、有关相机的信息、缩略图图像以及所有这些有时以不同格式显示的内容:exif、photoshop、,因此,您不能假设文件的大小与要在屏幕上描绘的计算机中的图像有关,也不能假设需要某些特殊属性。要获取这些数据以便进一步使用,您可以执行以下操作:

NSData *imgData = [NSData dataWithContentsOfURL:url];

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

NSImage *image = [[NSImage alloc] initWithContentsOfURL:url];  // similar methods:see the docs
如果你现在认为这是转换成可可结构的文件图像数据,那你就错了。NSImage类的对象不是图像,它只是零个、一个或多个图像表示的容器。Gif、jpg、png图像始终只有一个表示,tiff可能有一个或多个,ICN大约有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];
}
for(i=0;i=8){
NSInteger paddingBits=[rep bitsPerPixel]-[rep bitsPerSample]*[rep samplesPerPixel];
//测试每行是否有填充字节
NSInteger paddingBytes=[rep bytesPerRow]-([rep bitsPerPixel]*[rep pixelsWide]+7)/8;
NSU整数位图大小=[rep bytesPerRow]*[rep pixelsHigh];
}
另一句话:你说:

我扫描了一张带有Macintosh数百万种颜色的图像(.tiff) 表示每像素24位

不,不必如此。如果一个像素只有三个分量,由于一些优化规则,它可能不仅使用24位,有时还使用32位。问问销售代表,它会告诉你真相。并要求提供bitmsapFormat!(详情见文件)


最后:您不需要使用CG函数。NSImage和NSImageRep可以完成所有操作。

。tiff图像也可以压缩。但是,如果图像已压缩,当我在windows或mac中看到文件信息时,尺寸相同,即
348*580
。尺寸应该是压缩图像的尺寸,不是吗?在压缩过程中尺寸不会改变。改变的是,您没有存储每个像素的RGB值,而是找到了其他表示图像中像素颜色的方法。Ok。知道了。那么,你能告诉我解压
.tiff
图像的方法吗?这样我就可以正确地复制它了?你的代码已经得到了解压后的数据,这样你就可以真正信任那里的像素值了。+1谢谢你提供的信息!我肯定会检查你提出的意见陈述的数量。但是,回到我的问题,我需要解压缩图像以获得其中包含的确切信息。将其转换为
NSImage
NSData
将不起作用。你有什么想法吗?关于每像素的比特数,我不仅仅是假设。这行代码,
nsuiger numberOfBitsPerPixel=CGImageGetBitsPerPixel(imageRef),也返回24。我还使用您的代码进行了检查,结果发现图像只有一种表示形式,因此所有数据都保持不变。大小差异的基本问题是,作为输入的图像被压缩,需要解压缩。所以,总的来说,我需要一些算法或API来解压手头的图像。我不明白。NSBitmapImageRep中的数据将被解压缩。位图中的数据正好代表您在屏幕上看到的位和字节,大小为[rep bytesPerRow]*[rep pixelsHigh]。TIFFRepresentation方法以TIFF格式创建数据,该格式适合写入文件,但除此之外没有其他用途。我知道图像尺寸可用于计算大小,但我
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];
}