写真を表す ALAsset が与えられた場合、画像を UIImageView にロードしたり、aspectRationThumnail メソッドを使用したりせずに、写真のサイズ (高さと幅) を取得することは可能ですか?
5 に答える
注意: iOS 5.1 では、ALAssetRepresentation インスタンスの新しいプロパティ ディメンションが導入されています。これは、元の画像の寸法を含む CGSize 構造体を返します。これは、将来的にこの問題の最良の解決策になる可能性があります。
乾杯、
ヘンドリック
float width = asset.defaultRepresentation.dimensions.width;
float height = asset.defaultRepresentation.dimensions.height;
高速で安定しており、実際の寸法が得られます。動画のALAssetで使用しました。
イメージ サイズにアクセスするより簡単な方法は、 を使用すること[ALAssetRepresentation metadata]
です。私がテストした画像では、これにはとNSDictionary
という名前のキーが含まれていました。これらは、予想される値を持つオブジェクトでした。PixelWidth
PixelHeight
NSNumber
ただし、見つけられる正確なキーについて特定の保証はないようです。そのため、それらのキーがメタデータにない場合にアプリが対処できることを確認してください。速度とスレッド セーフに関する注意事項については、iOS ALAsset イメージ メタデータも参照してください。
比較
iPad のアセット ライブラリ全体で、両方の方法 (CGImageSourceRef に画像データを読み込むか、メタデータを読み取る) をテストしました。どちらのメソッドも、FLT_EPSILON 内に同じサイズを返しました。2 倍の時間がかかった 2 つの外れ値を除けば、16 回の繰り返しの実行時間は非常に類似していました。
メソッド | 平均時間 +/- 95% 信頼度 CGImageSourceRef からのサイズ | 0.1787 +/- 0.0004 メタデータからのサイズ | 0.1789 +/- 0.0015
したがって、どちらの方法もパフォーマンス上の利点はありません。メタデータ ディクショナリは、イメージ データを読み取ることによってオンデマンドで構築される可能性が十分にあります。
アップデート
コメントに記載されているように、これは最初に提供されたとおりには機能しませんでした。私はそれを修正しましたが、OPが回避しようとしていたすべての画像データをロードするようになりました。データを画像に解凍するという追加の、さらに悪い手順を回避します。
defaultRepresentation
ALAssetの を取得します。- ALAssetRepresentation のデータを取得します。
- この便利な sizeOfImageAtURL関数の適応を使用します。ありがとう、シュパコフスキー。
以下のコードは、上記の手順を表しています。
// 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
...