ALAsset图像大小

给定一个代表照片的ALAsset,是否可以检索照片的大小(高度和宽度)而无需将图像加载到UIImageView中,也不使用aspectRationThumnail方法?

请注意:iOS 5.1为ALAssetRepresentation实例引入了新的属性维度。 这将返回具有原始图像尺寸的CGSize结构,并且可能是将来解决此问题的最佳解决方案。

干杯,

亨德里克

 float width = asset.defaultRepresentation.dimensions.width; float height = asset.defaultRepresentation.dimensions.height; 

它快速,稳定,并给出实际尺寸。 我已将它与ALAssetvideo一起使用。

访问图像大小的更简单方法是通过[ALAssetRepresentation metadata] 。 在我测试的图像上,这个NSDictionary包含名为PixelWidthPixelHeight键,它们是具有您期望值的NSNumber对象。

但是,似乎没有关于您将找到的确切密钥的特别保证,因此请确保您的应用可以处理这些密钥不在元数据中的情况。 另请参阅iOS ALAsset图像元数据 ,了解有关速度和线程安全性的一些注意事项。

对照

我在iPad的整个资产库中测试了两种方法 – 在CGImageSourceRef中加载图像数据或读取元数据。 两种方法都返回相同的大小到FLT_EPSILON内。 除了2个exception值花费了两倍的时间外,16次重复的运行时间非常相似:

方法| 平均时间+/- 95%置信度
来自CGImageSourceRef |的大小  0.1787 +/- 0.0004
元数据的大小|  0.1789 +/- 0.0015

因此,这两种方法都没有性能优势。 完全有可能通过读取图像数据按需构造元数据字典。

更新

如评论中所述,这不像最初提供的那样有效。 我已修复它,但它现在加载了OP试图避免的所有图像数据。 它仍然避免了将数据解压缩成图像的额外且更糟的步骤。

  1. 获取ALAsset的defaultRepresentation
  2. 获取ALAssetRepresentation的数据。
  3. 使用这个方便的sizeOfImageAtURL函数的改编。 谢谢你,shpakovski。

下面的代码代表上面的步骤。

 // This method requires the ImageIO.framework // This requires memory for the size of the image in bytes, but does not decompress it. - (CGSize)sizeOfImageWithData:(NSData*) data; { CGSize imageSize = CGSizeZero; CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef) data, NULL); if (source) { NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO] forKey:(NSString *)kCGImageSourceShouldCache]; NSDictionary *properties = (__bridge_transfer NSDictionary*) CGImageSourceCopyPropertiesAtIndex(source, 0, (__bridge CFDictionaryRef) options); if (properties) { NSNumber *width = [properties objectForKey:(NSString *)kCGImagePropertyPixelWidth]; NSNumber *height = [properties objectForKey:(NSString *)kCGImagePropertyPixelHeight]; if ((width != nil) && (height != nil)) imageSize = CGSizeMake(width.floatValue, height.floatValue); } CFRelease(source); } return imageSize; } - (CGSize)sizeOfAssetRepresentation:(ALAssetRepresentation*) assetRepresentation; { // It may be more efficient to read the [[[assetRepresentation] metadata] objectForKey:@"PixelWidth"] integerValue] and corresponding height instead. // Read all the bytes for the image into NSData. long long imageDataSize = [assetRepresentation size]; uint8_t* imageDataBytes = malloc(imageDataSize); [assetRepresentation getBytes:imageDataBytes fromOffset:0 length:imageDataSize error:nil]; NSData *data = [NSData dataWithBytesNoCopy:imageDataBytes length:imageDataSize freeWhenDone:YES]; return [self sizeOfImageWithData:data]; } - (CGSize)sizeOfAsset:(ALAsset*) asset; { return [self sizeOfAssetRepresentation:[asset defaultRepresentation]]; } 
 float width = CGImageGetWidth(asset.defaultRepresentation.fullResolutionImage); float height = CGImageGetHeight(asset.defaultRepresentation.fullResolutionImage); 

或者相同的asset.defaultRepresentation.fullScreenImage