経緯
iOSでPhotos Framework経由で写真を取得する際にサイズを計算したいことがあったのですが、実際のサイズとだいぶズレていたので正しいサイズを取得できた経緯を残したいと思います。
動いたコード
Objective-Cですが、Swiftでも変わらず使えると思います。
[asset requestContentEditingInputWithOptions:[[PHContentEditingInputRequestOptions alloc] init] completionHandler:^(PHContentEditingInput * _Nullable contentEditingInput, NSDictionary * _Nonnull info) {
NSError *error = nil;
NSString *url = contentEditingInput.fullSizeImageURL.path;
NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:url error:&error];
if (!error) {
NSInteger size = [[attributes objectForKey:NSFileSize] integerValue];
} else {
// error !
}
}];
結論としては、 NSFileManager
の attributesOfItemAtPath:
で渡ってくるDictionaryの中の NSFileSize
というKeyにbytesでデータが入っていました。
これを1024で割っていけば、 KB, MB, GB, ... と変換することができます。
試したコードたち
まずは UIImage → NSData に変換をかけて length
プロパティでサイズを計算しようとしました。
確かにサイズは取得できたように思えたのですが、実際のサイズよりもかなり大きくなってしまいました。
これは PNG
や JPEG
などが、このデータに対して圧縮をかけているのが原因だと思います。なので、他の拡張子などに対しては有効かもしれません (未検証)
UIImageJPEGRepresentation(image, 1.0f).length;
// or UIImagePNGRepresentation(image).length;
次に、 UIImage.size をつかって計算しようと思いました。結果は上と同じになります。 width
, height
はピクセル数を意味しているので当たり前といえば当たり前ですが...
// imageのwidth, height の計算
CGFloat w = image.size.width;
CGFloat h = image.size.height;
// 表現データに応じて、なにかしらをかけてあげる (4byteなのかとか色々ね)
CGFloat size = (w * h) * α;
次に、 sizeof
を使ってデータを計算しようと思いました。 sizeof
は確保メモリ領域の取得なので今回の話とはそもそも違うことだったので早々に諦めました。