核心图像会立即加载图像数据吗?

3

假设我想要查找图像的大小,这样如果用户尝试在我的iPad应用程序中加载一张10,000x10,000像素的图像,我就可以向他们呈现一个对话框而不会崩溃。 如果我使用[UIImage imageNamed:][UIImage imageWithContentsOfFile:],那么它将立即将潜在的大型图像加载到内存中。

如果我改用Core Image,就像这样:

CIImage *ciImage = [CIImage imageWithContentsOfURL:[NSURL fileURLWithPath:imgPath]];

然后询问我的新CIImage的大小:

CGSize imgSize = ciImage.extent.size;

这会将整张图片加载到内存中来告诉我吗?或者只是查看文件的元数据来发现图片的大小?

1个回答

9
imageWithContentsOfURL函数会将图像加载到内存中。
幸运的是,在iOS4中,苹果实现了CGImageSource,可以读取图像元数据而不将实际像素数据加载到内存中。您可以在这篇博客文章中了解如何使用它(方便的是,它提供了一个代码示例,说明如何获取图像尺寸)。
编辑:在此粘贴代码示例以防链接失效:
#import <ImageIO/ImageIO.h>

NSURL *imageFileURL = [NSURL fileURLWithPath:...];
CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)imageFileURL, NULL);
if (imageSource == NULL) {
    // Error loading image
    ...
    return;
}

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                     [NSNumber numberWithBool:NO], (NSString *)kCGImageSourceShouldCache,nil];
CFDictionaryRef imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, (CFDictionaryRef)options);
if (imageProperties) {
    NSNumber *width = (NSNumber *)CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelWidth);
    NSNumber *height = (NSNumber *)CFDictionaryGetValue(imageProperties, kCGImagePropertyPixelHeight);
    NSLog(@"Image dimensions: %@ x %@ px", width, height);
    CFRelease(imageProperties);
}

完整的API参考文档在这里也可以找到


啊,糟糕,CIImage不能满足我的需求,但是好在还有其他的东西。我不知道是否有一种方法可以将数据中的图像调整大小为更易处理的尺寸,这样我就可以向用户呈现一个较小版本的巨大图像,而不仅仅是一个显示“无法显示”的对话框。 - Cory Imdieke
确实,我做过这件事。你可以将此帖子中描述的方法包含在你的类中,甚至像这样将该方法添加为UIImage的类别(参见) (你可以将其添加到一个前缀/头文件类中,然后它就成为任何UIImage都可以使用的方法了)! - andycam
啊,但是那种方法需要将UIImage呈现出来才能调整大小,这意味着它会在内存中 - 因此,在我调整大小之前,一个巨大的图像会在初始UIImage创建时使应用程序崩溃。 - Cory Imdieke
正确。我以为那是唯一的方法,但根据这个很棒的答案,CGImageSource也可以处理它! - andycam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接