如何从ALAssetRepresentation创建有效的CGImageSourceRef?

8
我正在尝试使用CGImageSourceCreateThumbnailAtIndex来有效地创建调整大小的图像版本。我有一些现有的代码,可以对来自磁盘的图像进行此操作,现在我正在尝试使用来自ALAssetsLibrary的图像。
这是我的代码:
ALAsset *asset;
ALAssetRepresentation *representation = [asset defaultRepresentation];
CGImageRef imageRef = [representation fullResolutionImage];

CGDataProviderRef provider = CGImageGetDataProvider(imageRef);
CGImageSourceRef sourceRef = CGImageSourceCreateWithDataProvider(provider, NULL);

NSDictionary *resizeOptions = @{
  kCGImageSourceCreateThumbnailWithTransform : @YES,
  kCGImageSourceCreateThumbnailFromImageAlways : @YES,
  kCGImageSourceThumbnailMaxPixelSize : @(2100) 
};

CGImageRef resizedImage = CGImageSourceCreateThumbnailAtIndex(source, 0, resizeOptions);

问题在于resizedImage为空,而CGImageSourceGetCount(sourceRef)返回0。虽然数据提供者中有很多数据,但数据似乎是有效的图像数据。这个ALAsset来自iPhone 4S相机胶卷。
我错过了什么?为什么CGImageSourceCreateWithDataProvider()会创建一个没有图像的图像源呢?

顺便提一下,将非对象字面量“YES”放入您的字典字面量中会出现问题。您需要使用“@YES”。 - Peter Hosey
哦,没错。实际上在我的代码中是 kCFBooleanTrue,但我不想在这里展示所有的转换。我会修复它的。 - BJ Homer
4个回答

4

CGImageSource是用于反序列化序列化的图像,例如JPEG、PNG等。

CGImageGetDataProvider返回图像的原始像素数据提供程序。它不会以某些外部格式返回序列化字节。CGImageSource无法知道给定的原始像素数据在哪种像素格式(颜色空间、每组件位数、alpha排列等)中。

您可以尝试获取资源副本的URL,并将其提供给CGImageSourceCreateWithURL。如果这样做不起作用(例如,不是文件URL),则必须通过CGImageDestination运行图像,并使用输出位置创建CGImageSource。

(另一种尝试的方法是查看rep的filename是否实际上是完整路径,Cocoa经常误用术语。但您可能不应该指望这点。)


啊,这很有道理。如果我通过-getBytes:length:offset:error:ALAssetRepresentation获取序列化数据,并将其制作成图像源,那么一切都可以正常工作。 - BJ Homer
@BJHomer:实际上,我认为它返回像素;如果它返回某些外部格式(考虑到representationForUTI:的存在是有道理的),那么你可能应该只使用它。 - Peter Hosey
@HeathBorders:我的猜测是,如果您使用数据提供程序创建了CGImages,并且想要检索您创建图像的数据提供程序,则可以这样做。但即使如此,我也不知道为什么您要这样做。 - Peter Hosey

2
你可以尝试的一件事是使用资产副本的 CGImageWithOptions: 方法。 文档声称:

此方法返回可用的最大和最佳表示形式,以任何方式未经调整。

但是它也是关于 fullResolutionImage 的,如果它们都做同样的事情,我不确定为什么这个类会有两种方法。我想知道这是否是复制和粘贴错误。
尝试使用一堆缩略图创建选项来使用 CGImageWithOptions: 并查看发生了什么。

这可能会起作用;在我的情况下,我有现有的代码应用了正确的选项并处理了一些其他处理,所以我真的只想将CGImageSourceRef传递给现有的代码,而不是复制它。但在另一种情况下,这可能是有意义的。 - BJ Homer

1

第三个选项是代表的fullScreenImage。根据您需要的“缩略图”类型,使用此选项可能会更便宜和/或更简单,因为它不会超过设备屏幕的大小(大约)。


0

这也可以帮助...

ALAssetRepresentation* rep = [asset defaultRepresentation];

NSDictionary* options = [[NSDictionary alloc] initWithObjectsAndKeys:
                     (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailWithTransform,
                     (id)kCFBooleanTrue, (id)kCGImageSourceCreateThumbnailFromImageAlways, 
                     (id)[NSNumber numberWithDouble:400], (id)kCGImageSourceThumbnailMaxPixelSize, 
                     nil];

CGImageRef image = [rep CGImageWithOptions:options];

请问你能否提供更多关于你的解决方案的详细信息? - abarisone

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