tah nn

主にアプリ開発の技術メモを残していきます。

【Objective-C】SDWebImageで画像サイズを変える

SDWebImageはFacebookアプリにも使われていると言われている、ものすご便利〜なライブラリです。

  • SDWebImage

 https://github.com/rs/SDWebImage

サーバーからイメージを取得する前に、アプリ側で画像サイズ変えられないですか?みたいな事態が生じたので、めんどくさいな〜と思いつつ、方法を探してみました。デリゲートメソッドを使用する方法です。

まずヘッダファイルではSDWebImageManagerDelegateプロトコルを採用します。

// HogeFugaViewController.h
@interface HogeFugaViewController : UITableViewController <SDWebImageManagerDelegate>

どこかでデリゲートを設定します。

// HogeFugaViewController.m
// webイメージ読み込みデリゲート設定
SDWebImageManager.sharedManager.delegate = self;

デリゲートメソッドを実装します。

// HogeFugaViewController.m
- (UIImage *)imageManager:(SDWebImageManager *)imageManager transformDownloadedImage:(UIImage *)image withURL:(NSURL *)imageURL
{
    /*イメージをリサイズする*/
    CGSize resizedImageSize = CGSizeMake(50, 50);
    UIGraphicsBeginImageContextWithOptions(resizedImageSize, NO, 0.0);
    [image drawInRect:CGRectMake(0, 0, resizedImageSize.width, resizedImageSize.height)];
    UIImage* resizedImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    image = resizedImage;
    return image;
}

上記のように実装するとSDWebImageライブラリを使って画像を設定する際、画像がキャッシュに保存される前にイメージをリサイズしてくれます。

NSURL* url = /*イメージのURL*/;
UIImage* placeholder = /*プレースホルダイメージ*/;
[cell.hogeImage setImageWithURL:url placeholderImage:placeholder];

しかし、上記の対応だけではSDWebImageでキャッシュするイメージがスケール1.0で保存されてしまっていました。。
SDWebImageライブラリだとURLに @2x という名前がないとUIImageのスケールが 1.0 で保存されるっぽいです。(ちゃんとは確かめてません)
スクリーンのスケールからRetinaディスプレイかどうか判断して,Retinaディスプレイの場合はUIImageのスケールを2倍に設定し直すようにライブラリを修正しました。(微妙な対応ですね。。もっといい方法はないでしょうか)

// UIImageView+WebCache.m
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock {
/*略*/
            if (!wself) return;
            dispatch_main_sync_safe(^{
                if (!wself) return;
                if (image) {       //ここから
                    if ([UIScreen mainScreen].scale == 2.0)
                    {
                        wself.image = [UIImage imageWithCGImage:image.CGImage scale:2.0f orientation:UIImageOrientationUp];
                    }
                    else
                    {                  //ここまで追記
                        wself.image = image;
                    }
                    [wself setNeedsLayout];
                }
/*略*/
}

以上です。



※補足

上記の例ではイメージのサイズを幅50、高さ50で固定でしたので、以下のライブラリを使えば出来そうです。
https://github.com/toptierlabs/ImageCacheResize

ただし、動的にサイズを変えたいときはデリゲートを使うのが良さそうです。

■参考ページ
https://github.com/rs/SDWebImage
http://hackemist.com/SDWebImage/doc/Protocols/SDWebImageManagerDelegate.html#//api/name/imageManager:transformDownloadedImage:withURL:
http://stackoverflow.com/questions/12928103/sdwebimage-process-images-before-caching