17
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

NSDataのまま画像のサイズを取得する

Last updated at Posted at 2013-04-09

画像のサイズはCGImageRefやUIImageのインスタンスを作成して取得することができます。
しかしながら、それは同時に画像を展開するということでもあります。
サイズを取りたいだけで、展開まで必要ない場合には、
メモリとCPUパワーが若干もったいない気がします。

######※コメントからのご指摘により、どうやら現時点のUIImageの実装では画像のピクセルデータ展開は描画時まで遅延されるようです。なのでべたにUIImageを作成してもそれはオーバーヘッドにはならない、ということがわかりました。今後この挙動が変わるとは到底思えませんが、ただあくまでも現時点でのUIImageの実装に依存している挙動であることは頭の片隅に入れておいた方がいいかもしれません。######

通常画像圧縮データにはヘッダがあるわけで、普通に考えればピクセルデータを展開せずともサイズくらい取得できるはずです。
まあ、もちろん自分で画像形式等やるのは面倒なので、iOS SDKに乗っかります。

というわけで、ImageIO.frameworkを使っての実装例を挙げたいと思います。

ヘッダー(NSData+imageSize.h)

#import <Foundation/Foundation.h>

@interface NSData (imageSize)
- (CGSize)imageSize;
@end

実装(NSData+imageSize.m)

#import "NSData+imageSize.h"

#import <ImageIO/ImageIO.h>
@implementation NSData (imageSize)
- (CGSize)imageSize
{
    CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)self, NULL);
    if(imageSource == NULL)
        return CGSizeZero;
    dispatch_async(dispatch_get_main_queue(), ^{ CFRelease(imageSource); });
    
    NSDictionary *imageProperties = (__bridge_transfer NSDictionary *)CGImageSourceCopyPropertiesAtIndex(imageSource, 0, NULL);
    if(imageProperties == NULL)
        return CGSizeZero;
    
    CGSize size =
    {
        [imageProperties[(id)kCGImagePropertyPixelWidth] floatValue],
        [imageProperties[(id)kCGImagePropertyPixelHeight] floatValue],
    };
    
    return size;
}
@end

17
18
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?