ALAsset Image Size

核能气质少年 提交于 2019-12-05 14:13:14

Just a note: iOS 5.1 introduces a new property dimensions for an ALAssetRepresentation instance. This returns a CGSize structure with the dimensions of the original image and might be the best solution for this problem in the future.

Cheers,

Hendrik

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

it fast, stable, and gives the actual dimensions. I've used it with ALAsset of videos.

A simpler way to access the image size is through [ALAssetRepresentation metadata]. On the images I tested on, this NSDictionary contained keys named PixelWidth and PixelHeight, which were NSNumber objects with the values you'd expect.

However, there seem to be no particular guarantees about the exact keys you'll find, so make sure your app can deal with cases where those keys aren't in the metadata. Also see iOS ALAsset image metadata for some cautions about speed and thread safety.

Comparison

I tested both methods - loading the image data in CGImageSourceRef or reading the metadata - on my iPad's entire asset library. Both methods returned the same sizes to within FLT_EPSILON. Apart from 2 outliers which took double time, the run times out of 16 repetitions were very similar:

Method                     | Mean time +/- 95% confidence
Size from CGImageSourceRef |    0.1787 +/- 0.0004
Size from metadata         |    0.1789 +/- 0.0015

So, neither method has a performance benefit. It is entirely possible that the metadata dictionary is constructed on demand by reading the image data.

Update

This didn't work as originally offered, as noted in the comments. I've fixed it, but it now loads all the image data, which the OP was trying to avoid. It still avoids the additional, and still worse step, of decompressing the data into an image.

  1. Get the defaultRepresentation of the ALAsset.
  2. Get the data for the ALAssetRepresentation.
  3. Use an adaptation of this handy sizeOfImageAtURL function. Thank you, shpakovski.

The code below represents the steps above.

// 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]];
}
user953175
float width = CGImageGetWidth(asset.defaultRepresentation.fullResolutionImage);
float height = CGImageGetHeight(asset.defaultRepresentation.fullResolutionImage);

or same for asset.defaultRepresentation.fullScreenImage...

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!