Given an ALAsset that represents a photo, is it possible to retrieve the size of the photo (height and width) without loading the image into a UIImageView and also without using the aspectRationThumnail method?
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.
- Get the
defaultRepresentation
of the ALAsset. - Get the data for the ALAssetRepresentation.
- 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]];
}
float width = CGImageGetWidth(asset.defaultRepresentation.fullResolutionImage);
float height = CGImageGetHeight(asset.defaultRepresentation.fullResolutionImage);
or same for asset.defaultRepresentation.fullScreenImage
...
来源:https://stackoverflow.com/questions/10067765/alasset-image-size