その後のその後

iOSエンジニア 堤 修一のブログ github.com/shu223

Assets Library からの読み込みを高速化するための試行錯誤

先日出した高速スライドショーアプリは最高0.1s/枚とうたっていますが、実際のところ、なかなか1秒に10枚表示とはいきません。


ALAsset から UIImage へ変換する部分の実装ではこんな感じになっているのですが、

ALAsset *aseet = (ALAsset *)[self.assets objectAtIndex:currentAssetIndex];
ALAssetRepresentation *representation = [asset defaultRepresentation];
UIImage *img = [UIImage imageWithCGImage:[representation fullScreenImage]
                                   scale:[representation scale]
                             orientation:[representation orientation]];

ここで処理時間を計測してみたところ、解像度の高い画像では 0.3s 〜 0.6s 程度かかっているようです。


これを高速化すべく、試行錯誤してみました。

方法1:ALAssetRepresentation から fullScreenImage メソッドで CGImageRef を取り出しているところを、fullResolutionImage で取り出してみる

fullScreenImage で取り出すってことは一度スクリーンサイズに画像をスケーリングするわけで、その後UIImageViewにつっこむ際にもスケーリングするので、スケーリング処理が2回入ることになります。
そのまま取り出した方が速そう、ってことで下記のように fullResolutionImage に変えてみました。

ALAsset *aseet = (ALAsset *)[self.assets objectAtIndex:currentAssetIndex];
ALAssetRepresentation *representation = [asset defaultRepresentation];
UIImage *img = [UIImage imageWithCGImage:[representation fullResolutionImage]
                                   scale:[representation scale]
                             orientation:[representation orientation]];


(結果)
速くなりました。1200 x 1600 px で 0.05s とか。
ただ iPhone4 のカメラの解像度である 1936 x 2592 px だと0.1s 〜 0.5s程度かかることも。

方法2:ALAsset から直接 thumbnail メソッドで CGImageRef を取り出す

ALAsset *asset = (ALAsset *)[self.assets objectAtIndex:currentAssetIndex_];
UIImage *img = [UIImage imageWithCGImage:[asset thumbnail]];

チョッパヤ。0.003sとか。
画像サイズが固定なので速度も安定。
ただし150 x 150 px なので当然ながら画質は相当低くなります。

方法3:キャッシュ

いずれの方法も試してませんが・・・

  • 案1:ALAssetの配列生成時にUIImageまで変換しておく
    • 枚数多いとメモリ食うので50枚ぐらいまで?
  • 案2:別スレッドでUIImageへの変換を行う
    • 表示側(メインスレッド)は追いついてしまったらポーリングして待つ
  • 案3:画像を縮小してドキュメントフォルダに保存)
    • 枚数に依存しない。でもファイル読み込みに結局時間かかる?

結論

i走馬灯では以下のように fullResolutionImage と thumbnail のハイブリッド仕様としました。

  • 基本的に fullResolutionImage で CGImageRef を取り出す
  • ユーザーがスライダーで最高速を選択している場合のみ、ブーストボタンを出す。それを押すとthumbnail表示に変わる


※本実装を施したバージョン1.2は申請中です。