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 包含名为PixelWidthPixelHeight 的键,它们是具有您期望值的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: CGImageSourceCreateWithURL CFURLCreateDataAndPropertiesFromResource failed with error code -11 由于某种原因。想知道 ALAsset 网址是否与此兼容? @CoDEFRo:是的,恐怕我实际上并没有测试将 NSURL 用于 ALAsset 对象的步骤。似乎没有办法从 URL 加载数据,所以我不确定你应该用它做什么。我进行了编辑以提供有效的代码,并提出了一个替代答案。 我认为 sizeOfImageWithData 方法不正确 - 在我的测试中,我还需要查看 Orientation 标志。当我在纵向模式下拍摄图像时,我得到宽度/高度反转和 6 的方向值(镜像纵向模式)。无论如何 - 我认为它也需要查看 kCGImagePropertyOrientation。【参考方案5】:
float width = CGImageGetWidth(asset.defaultRepresentation.fullResolutionImage);
float height = CGImageGetHeight(asset.defaultRepresentation.fullResolutionImage);

asset.defaultRepresentation.fullScreenImage 或相同...

【讨论】:

在大图像上效果不佳

以上是关于ALAsset 图像大小的主要内容,如果未能解决你的问题,请参考以下文章

带有 ALAsset 缩略图的低清晰度

如何使用 ALAsset 获得图像的裁剪版本?

ALAsset 库 + 文档目录图像?

iOS 在 UITableView 中显示来自 ALAsset 的图像

如何从 ALASSET ios 获取视频大小

ALAsset 缩略图有黑色背景