React Native+Expo ~ 写真の複数選択はMediaLibraryで!
それはそれは長いこと放置してしまったアプリ開発。
放置するきっかけは、写真の複数選択がImagePickerでできないために行き詰ってしまったことでした。
ReactNativeでカメラロールから写真を複数枚選択する処理の実装 - production.log
React Native, Expoを使った画像処理の流れ | Narumium Blog
自分では上記の記事のも上手く実装できず。。。
写真の選択から加工までImagePicker+ImageManipulatorに頼り切ってたので意気消沈です。 そもそもなんで一枚ずつしか選択できないなんて仕様なんだ。
でもよくよく調べてみたら、MediaLibraryの方に写真や動画やらの扱いが搭載されているようですね。
MediaLibrary - Expo Documentation
意外と例が見当たらなかったので、軽く触れておこうと思います。
requestPermissionsAsync
ImagePIckerの時もですが、カメラロールにアクセスするにはPermissionが必要ですね。
const getPermissionAsync = async (): Promise<void> => { if (Platform.OS !== 'ios') return; const { status } = await MediaLibrary.requestPermissionsAsync(); status !== 'granted' && alert('Sorry, we need camera roll permissions to make this work!'); };
getAssetsAsync
そしてこちらが写真や動画にアクセスするメソッドです。公式にある通りですが、mediaTypeで写真か動画か両方かなどの指定、はじめからいくつのデータを取ってくるだとか、IDでいくつ以降だとか、日付でいつ以前・以降だとか、いろいろ指定できます。
下記の例では写真のみを指定し、今日から2週間前から最初の10枚を選択しています。
const media = await MediaLibrary.getAssetsAsync({ first: 10, mediaType: ['photo'], createdAfter: moment(new Date()).add(-14, 'days').toDate(), });
getAssetInfoAsync
そして、アクセスした写真や動画などのオブジェクトを、さらにgetAssetInfoAsyncの方に投げます。上記で複数選択している場合はオブジェクトの配列になっているので、mapなどで個々にメソッドに入れてやることになりますね。
const photo = await MediaLibrary.getAssetInfoAsync(media.assets[4]);
これによって、uriをはじめ、locationやorientationなどの情報のほか、さらに詳細なメタデータexifにもアクセスすることができます。
所感
まだ大量の写真で試してはいないけれど、ロケーションとかでデータを絞りたい場合は本当はgetAssetsAsyncの時点でそこまでアクセスできたらいいのになぁというところ。
getAssetsAsyncでは何千というデータにアクセスしてるはずだけど、メタデータ的な部分のみなので時間もさほどかかってないはず。
getAssetInfoAsyncもそれほど問題ない、か?その後でメタデータを使ってフィルターなりして、ImageManipulatorに渡して基本的な処理をするなどできるはず。
さて、またアプリ開発もいろいろいじってみよう!