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:画像を縮小してドキュメントフォルダに保存)
- 枚数に依存しない。でもファイル読み込みに結局時間かかる?