一覧画像は絶対Thumbnailで読み込むべし

By daichi1128
このエントリをはてなブックマークに追加このエントリをdel.icio.usに追加このエントリをLivedoor Clipに追加このエントリをYahoo!ブックマークに追加このエントリをFC2ブックマークに追加このエントリをNifty Clipに追加このエントリをPOOKMARK. Airlinesに追加このエントリをBuzzurl(バザール)に追加このエントリをChoixに追加このエントリをnewsingに追加

こんにちは。daichi1128です。

Androiderのみなさん。今日も画像、読み込んでますでしょうか。

ContentResolverで画像を読み込む場合、
MediaStore.Images.Media
MediaStore.Images.Thumbnails
の2つのURIが使えます。

それぞれのEXTERNAL_CONTENT_URIから、SDカードの中の画像を取り出せますね。

例えば、こんなアプリがあったとしましょう。
select

画面下のGalleryでSDカードの画像を一覧表示したい。

画像の一覧を取得するには、
MediaStore.Images.Media
MediaStore.Images.Thumbnails
これらのURIから一覧を取得できる。

が、どうもMediaには画像があるけれども、Thumbnailsに存在しないケースがある。

なので、あるはずの画像全ての一覧を表示するにはMediaStore.Images.Mediaの方でクエリを叩かなければならない。

しかし、こいつでロードすると、Thumbnailsは得られない。

そのため、MediaStore.Images.MediaのURIから縮小した画像をそれぞれ読み込んでいたのですが、これだと読み込みが遅い。

大きい画像を一旦縮小してから読み込んでいるのだから致し方ないところ。

ここをどうにか早くできないかといろいろ調べてみた所、ありました。

MediaStore.Images.Thumbnails.getThumbnail(ContentResolver cr, long origId, int kind, BitmapFactory.Options options)
です。

origIdに画像IDを、kindにThumbnailの種別を(MINI_KIND or MICRO_KIND)を指定して、オリジナル画像に対応するThumbnail画像を返してくれます。
こいつのすばらしい所は、サムネイル画像がなければ、生成して返してくれる所。
なので、サムネイル一覧から取得した場合に起きたような画像の不整合は解消されます。

が、しかし、このAPIはAndroid1.6では使えない。。。
# Xperiaでこれを使いたかったのに。。。

Xperiaでこのメソッドを使うにはどうしたらよいか。

作ってしまえばよいです。

Androidはソースコードが公開されてるので、最新バージョンのソースコードを入手することができます。
そのソースには、getThumbnailメソッドの実装が載ってます。
それをパクってしまうのが一番てっとり早いでしょう。

ThumnailUtilというクラスにgetThumbnailの実装がありますが、丸ごと持ってくるとandroidで使用しているnativeコードに依存してしまうので、今回使用しない部分(videoのサムネイルやexif情報関連など)を削除しました。

これを使って、オリジナル画像を縮小して読み込む方式から、MICRO_KINDのサムネイルを読む込む方式に変更したところ、大幅にパフォーマンスが改善されました!

MICRO_KINDだと96×96の画像が読み込まれます。オリジナルだと800×480などだったので、それは相当早くなりますよね。。。

AsyncTaskで非同期にロードする必要がなくなるほどに早いです。

以下の2つのファイルを組み込めば使えるようになります。
パッケージ名は適宜置き換えてください。

ThumbnailUtil.java
MiniThumbFile.java

ThumbnailUtil#getThumbnailBitmapでサムネイル画像を取得できます。

関連する投稿