ALAsset 图像大小
Posted
技术标签:
【中文标题】ALAsset 图像大小【英文标题】:ALAsset Image Size 【发布时间】:2012-04-09 00:41:18 【问题描述】:给定一个表示照片的 ALAsset,是否可以在不将图像加载到 UIImageView 并且不使用 aspectRationThumnail 方法的情况下检索照片的大小(高度和宽度)?
【问题讨论】:
【参考方案1】:请注意: ios 5.1 为 ALAssetRepresentation 实例引入了一个新的属性维度。这将返回一个具有原始图像尺寸的 CGSize 结构,并且可能是未来解决此问题的最佳解决方案。
干杯,
亨德里克
【讨论】:
是的,这比我建议的任何一种方法都快得多。请问dimensons
属性是如何被发现的,因为它在 ALAssetRepresentation 类参考中没有提到,即使对于 iOS 5.1 也是如此?
这里在API差异中有提到:developer.apple.com/library/ios/#releasenotes/General/…【参考方案2】:
float width = asset.defaultRepresentation.dimensions.width;
float height = asset.defaultRepresentation.dimensions.height;
它快速、稳定并提供实际尺寸。我已经将它与 ALAsset 视频一起使用。
【讨论】:
【参考方案3】:访问图像大小的更简单方法是通过[ALAssetRepresentation metadata]
。在我测试的图像上,这个NSDictionary
包含名为PixelWidth
和PixelHeight
的键,它们是具有您期望值的NSNumber
对象。
但是,对于您将找到的确切密钥似乎没有特别的保证,因此请确保您的应用可以处理这些密钥不在元数据中的情况。另请参阅iOS ALAsset image metadata,了解有关速度和线程安全的一些注意事项。
比较
我在 iPad 的整个资产库上测试了这两种方法 - 在 CGImageSourceRef 中加载图像数据或读取元数据。两种方法都在 FLT_EPSILON 中返回相同的大小。除了 2 个异常值需要双倍时间外,16 次重复的运行时间非常相似:
方法 |平均时间 +/- 95% 置信度 来自 CGImageSourceRef 的大小 | 0.1787 +/- 0.0004 元数据的大小 | 0.1789 +/- 0.0015因此,这两种方法都没有性能优势。元数据字典完全可以通过读取图像数据按需构建。
【讨论】:
【参考方案4】:更新
正如 cmets 中所述,这与最初提供的不同。我已经修复了它,但它现在加载了 OP 试图避免的所有图像数据。它仍然避免了将数据解压缩为图像的额外且更糟糕的步骤。
-
获取 ALAsset 的
defaultRepresentation
。
获取 ALAssetRepresentation 的数据。
使用this handy 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]];
【讨论】:
感谢您抽出宝贵时间提出。当我这样做时,我得到 ImageIO:float width = CGImageGetWidth(asset.defaultRepresentation.fullResolutionImage);
float height = CGImageGetHeight(asset.defaultRepresentation.fullResolutionImage);
asset.defaultRepresentation.fullScreenImage
或相同...
【讨论】:
在大图像上效果不佳以上是关于ALAsset 图像大小的主要内容,如果未能解决你的问题,请参考以下文章