やさしい画像ギャラリー改善tips

 やさしい画像ギャラリー改善tips

A967476c5855d593710a9a580f6b2aed?s=128

Yuichi Maekawa

April 20, 2017
Tweet

Transcript

  1. やさしい 画像ギャラリー改善tips @kaelaela

  2.    まえかわ ゆういち(kaelaela) • Github: kaelaela • Twitter: kaelaela31 • 755というSNSを作っています

  3. 注意 画像ギャラリー ≠ 画像一覧 画像ギャラリーとは端末内の画像を選択する画面のこと

  4. 対象としている人 • 画像ギャラリーよくしたかったんだよね • いろいろ調べたけど諦めた • スケジュール的に泣く泣くある程度のものにしてた

  5. 対象じゃない人 • 画像ギャラリー作成は一通り悩んだ • うちには画像ギャラリーが必要ない

  6. 話さないこと • Intentの概念、使い方など • ContentResolverの説明など • 画像キャッシュに関すること • APIからリストを取得し表示すること

  7. ゴール 「簡単そうだな」 「画像選択画面のパフォーマンスを改善しました」リリース

  8. 画像ギャラリー苦しみあるある • スクロールするとカクつく • ローディングが終わらない or 何度も呼び出される • キャッシュが効くまでは遅い •

    Android標準のギャラリーが開く (Storage Access Framework)
  9. Storage Access Framework • MIME typeで指定できるが、関係のないフォルダの参照などもある • デザインの変更ができない • 公式ドキュメント

    https://developer.android.com/guide/topics/providers/document-provider.html //Build.VERSION.SDK_INT >=Build.VERSION_CODES.KITKA Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("image/*"); //画像のみの場合 startActivityForResult(intent, YOUR_REQUEST_CODE);
  10. Storage Access Framework • MIME typeで指定できるが、関係のないフォルダの参照などもある • デザインの変更ができない • 公式ドキュメント

    https://developer.android.com/guide/topics/providers/document-provider.html //Build.VERSION.SDK_INT >=Build.VERSION_CODES.KITKA Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("image/*"); //画像のみの場合 startActivityForResult(intent, YOUR_REQUEST_CODE); デザイナーが 許してくれない
  11. こんな画像ギャラリーにしたい • 読み込みとスクロールが早い • デザインが自由にできる • 自分たちのアプリで必要な機能に絞る

  12. 改善のポイント3つ • 画像管理方法を理解する • 適切なサイズの画像を使う • 使い方に合わせて表示する

  13. ポイント1: 画像の管理方法を理解する • 保存されている画像について • MediaStoreのイメージ図 • 画像へのアクセス方法

  14. 保存されている画像について 形式: 基本は撮影したjpgやダウンロードしたpng MediaStore:端末内データのメタ情報を提供している Audio, Files, Images, Video, MediaColumns https://developer.android.com/reference/android/provider/MediaStore.html#

  15. MediaStoreのイメージ図 Files - FileColumns - MEDIA_TYPE - MIME_TYPE - TITLE

    ... その他、有象無象 Audio - Media - Alubms - Artists ... Images - Media - Thumbnails - ImageColumns Video - Media(本体) - Thumbnails - VideoColumns
  16. 画像を取得 Files - FileColumns - MEDIA_TYPE - MIME_TYPE - TITLE

    ... その他、有象無象 Audio - Media - Alubms - Artists ... Images - Media - Thumbnails - ImageColumns Video - Media(本体) - Thumbnails - VideoColumns ここから取得 MediaStore.Images.Media
  17. 画像と動画を取得 Files - FileColumns - MEDIA_TYPE - MIME_TYPE - TITLE

    ... その他、有象無象 Audio - Media - Alubms - Artists ... Images - Media - Thumbnails - ImageColumns Video - Media(本体) - Thumbnails - VideoColumns ここから取得 =MediaStore.Filesで MEDIA_TYPE_IMAGE,MEDIA_TYPE_VIDEOを指定
  18. 画像へのアクセスの方法 ContentResolverでアクセス https://developer.android.com/reference/android/content/ContentResolver.html Cursorで取得 SQLでいう「CURRENT OFカーソル名」のカーソル

  19. 画像へのアクセスの方法 ContentResolver r = context.getContentResolver(); Cursor c = r.query(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, null,

    null, null, null); if (c != null) { c.moveToFirst(); while (!c.isAfterLast()) { String data = c.getString(c.getColumnIndex(MediaStore.Images.Thumbnails.DATA)); String imageId = c.getString(c.getColumnIndex(MediaStore.Images.Thumbnails.IMAGE_ID)); thumbnailPaths.add(data); thumbnailIds.add(imageId); c.moveToNext(); } c.close(); }
  20. 画像へのアクセスの方法 ContentResolver r = context.getContentResolver(); Cursor c = r.query(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, null,

    null, null, null); if (c != null) { c.moveToFirst(); while (!c.isAfterLast()) { String data = c.getString(c.getColumnIndex(MediaStore.Images.Thumbnails.DATA)); String imageId = c.getString(c.getColumnIndex(MediaStore.Images.Thumbnails.IMAGE_ID)); thumbnailPaths.add(data); thumbnailIds.add(imageId); c.moveToNext(); } c.close(); }
  21. ポイント2: 適切なサイズを使う たいていの記事では MediaStore.Images.Media.EXTERNAL_CONTENT_URI を使っているので、もとのサイズのイメージを読み込んでいる MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI を使いましょう Thumbnailのサイズ • MINI_KIND:

    512 x 384 • MICRO_KIND: 96 x 96
  22. MediaStoreのイメージ図 Files - FileColumns - MEDIA_TYPE - MIME_TYPE - TITLE

    ... その他、有象無象 Audio - Media - Alubms - Artists ... Images - Media - Thumbnails - ImageColumns Video - Media(本体) - Thumbnails - VideoColumns
  23. 注意 • Thumbnailは回転情報がなく、横向きで表示されるものもある 「 CursorJoinerを使ってMediaStore.Images.Thumbnailsに回転情報を追加する」 tomoima525さん http://qiita.com/tomoima525/items/762a55a86b3decf05d55 • Thumbnailをそのまま使用しないように気をつける MediaStore.Images.Thumbnails.IMAGE_IDとMediaStore.Images.Media._IDが等しいことを利用

  24. MediaStoreのイメージ図 Files - FileColumns - MEDIA_TYPE - MIME_TYPE - TITLE

    ... その他、有象無象 Audio - Media - Alubms - Artists ... Images - Media - _ID - Thumbnails - IMAGE_ID - ImageColumns Video - Media(本体) - Thumbnails - VideoColumns 等しい
  25. ポイント3: 使い方に合わせて表示する • メッセージやSNSなど: 今撮ったsnowの写真がほしい → 撮影した写真が上に来るように → 選択したらすぐに送信できるように •

    画像加工など: プレビューしてから選ぶかもしれない → 拡大縮小できるプレビューを挟む → サムネイルじゃだめ(えっ
  26. サンプルつくりました • 普通の3カラムサンプル • Facebook Messengerサンプル • InstagramのDMサンプル https://github.com/kaelaela/AndroidImageGallerySample ※API

    level 16以上
  27. ありがとうございました!