这几个月来一直让我发疯:我有一个小应用程序可以预览相机原始图像。由于有问题的文件可能非常大并且存储在缓慢的网络驱动器上,我想为用户提供一个停止加载图像的机会。
我很方便地找到了这个线程:
在 NSOperation 中取消 NSData initWithContentsOfURL
并且正在使用 Nick 非常方便的方法来缓存数据并能够在中途发出取消请求。
无论如何,一旦我有了我使用的数据:
NSImage *sourceImage = [[NSImage alloc]initWithData:data];
查看 Nikon .NEF 文件时会出现问题;sourceImage
仅返回缩略图而不是完整大小。显示佳能 .CR2 文件,事实上,任何其他 .TIFF 和 .JPEG 似乎都很好,并且sourceImage
是预期的大小。我检查了正在加载的数据量(使用NSLog
和[data length]
),似乎所有尼康文件的 12mb 都存在-initWithData:
如果我使用
NSImage *sourceImage = [[NSImage alloc]initWithContentsOfURL:myNEFURL];
然后我得到尼康文件的全尺寸图像,但应用程序当然会阻塞。
因此,在四处寻找开始感觉像是我一生的事情之后,我想我知道问题与尼康的元数据有关,指出文件的 DPI 是 300,而佳能等人是 72。
我希望一个解决方案是懒惰地访问文件:
NSImage*tempImg = [[NSImage alloc] initByReferencingURL:myNEFURL];
并在这里和其他地方看到了类似的帖子,我发现了一个简单的常见答案
[sourceImage setSize:tempImg.size];
但当然,这只是将小缩略图的大小调整到 3000x2000 左右。
我一直在搞乱以下内容,希望他们能提供一种从 .NEF 获得全局的方法:
CGImageSourceRef isr = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
CGImageRef isrRef = CGImageSourceCreateImageAtIndex(isr, 0, NULL);
和
NSBitmapImageRep *bitMapIR = [[NSBitmapImageRep alloc] initWithData:data];
但是检查这些尺寸会显示相似的缩略图宽度和高度。实际上,isrRef
返回的缩略图更小,小 4.2 倍。或许值得注意的是 300 / 72 == 4.2,因此isrRef
考虑到 DPI(可能)已经观察到的图像上的 DPI。
请!有人可以[很好地]让我摆脱痛苦并帮助我从加载的数据中获取全尺寸图像吗?!?!目前,我正在使用对文件扩展名不区分大小写的搜索对 NEF 文件进行特殊处理,然后使用阻止方法加载 URL。我必须对应用程序阻止进行打击,从长远来看,搜索不可能是万无一失的。
顺便说一句:这实际上是操作系统中的错误吗?看起来NSImage's -initWithData:
,-initWithContentsOfURL:
方法使用不同的引擎来实际渲染图像。假设-initWithURL:
简单地加载数据然后被渲染就像它已经被呈现给类一样是不合理的-initWithData:
吗?