
- カメラロールから写真を取得し、表示させる方法
について解説します。
この記事を読むことで、このようなアプリを作ることができます。
1. 概要
expo-image-pickerと言うExpoライブラリを使うことで、カメラロールから写真を取得することができます。
公式ドキュメント: ImagePicker
2. 実装
2.1 サンプルコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
import React from 'react'; import { View, StyleSheet, TouchableHighlight, Image, Text, AsyncStorage, } from "react-native"; import { Header } from 'react-native-elements'; import * as ImagePicker from 'expo-image-picker'; import Constants from 'expo-constants'; import * as Permissions from 'expo-permissions'; const PHOTO = "@photo" export default class AddPage extends React.Component { constructor(props) { super(props); this.state = { photo: "null" } } componentDidMount() { this.getPermissionAsync(); this.onLoad(); } onLoad = async () => { try { const Photo = await AsyncStorage.getItem(PHOTO); if(Photo) { const photo = JSON.parse(Photo); this.setState({photo: photo}); } } catch (e) { console.log(e) } } onSave = async(photo) => { try { const Photo = JSON.stringify(photo); await AsyncStorage.setItem(PHOTO, Photo); } catch (e) { console.log(e) } } delete = () => { this.setState({photo: "default"}) this.onSave("default") } getPermissionAsync = async () => { if (Constants.platform.ios) { const { status } = await ImagePicker.requestCameraRollPermissionsAsync(Permissions.CAMERA_ROLL); if (status !== 'granted') { alert('Sorry, we need camera roll permissions to make this work!'); } } }; pickImage = async (item) => { let result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.Images, allowsEditing: true, aspect: [4, 3], quality: 1, }); if (!result.cancelled) { this.setState({ photo: result.uri }); this.onSave(result.uri) } }; render() { return ( <View style={{ flex: 1,}}> <Header centerComponent={{ text: 'expo-image-picker', style: { color: 'lightblue', fontSize: 22, fontFamily: 'Baskerville-Bold' } }} backgroundColor= "black" /> <View style={{flex: 1, alignItems: 'center', justifyContent: 'center' }}> {this.state.photo == "default" ? <View style={styles.imageView}> <Text style={{color: "white", fontSize: 45, fontWeight: "bold", fontFamily: 'Baskerville-Bold'}}>No Image</Text> </View> : <Image source={{ uri: this.state.photo }} style={styles.imageView}/> } </View> <View style={{flex: 1, flexDirection: "row", alignItems: 'center', justifyContent: 'center' }}> <TouchableHighlight style={[styles.text, {marginRight: 30, backgroundColor: "hsla(0, 90%, 55%, 0.6)"}]} activeOpacity={0.6} underlayColor="hsla(0, 90%, 40%, 0.8)" onPress={()=>this.delete()} > <Text style={{color: "white", fontSize: 24}}>削除</Text> </TouchableHighlight> <TouchableHighlight style={[styles.text, {marginLeft: 30, backgroundColor: "hsla(210, 90%, 55%, 0.6)"}]} activeOpacity={0.6} underlayColor="hsla(210, 90%, 40%, 0.8)" onPress={()=>this.pickImage()} > <Text style={{color: "white", fontSize: 24}}>追加</Text> </TouchableHighlight> </View> </View> ); } } const styles = StyleSheet.create({ imageView: { width: '80%', height: '80%', borderRadius: 20, borderColor: "white", borderWidth: 1, backgroundColor: "lightgray", alignItems: "center", justifyContent: "center", }, text: { borderColor: "black", borderWidth: 2, borderRadius: 10, alignItems: "center", justifyContent: "center", height: 60, width: 140, backgroundColor: "white", shadowColor: "black", shadowOffset: { height: 4, width: 4 }, shadowRadius: 3, shadowOpacity: 0.6, }, }); |
3. インストール方法
expo-image-pickerライブラリを使う為、以下のコマンドでインストールします。
1 |
expo install --save expo-image-picker |
4. 使い方
4.1 サンプルコードについて解説
ImagePicker.requestCameraRollPermissionsAsync()
または、Permissions.askAsync(Permissions.CAMERA_ROLL)。ユーザーの写真にアクセスするためのアクセス許可を付与するようにユーザーに要求します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
componentDidMount() { this.getPermissionAsync(); ・・・ } ・・・ getPermissionAsync = async () => { if (Constants.platform.ios) { const { status } = await ImagePicker.requestCameraRollPermissionsAsync(Permissions.CAMERA_ROLL); if (status !== 'granted') { alert('Sorry, we need camera roll permissions to make this work!'); } } }; |
ImagePicker.launchImageLibraryAsync
カメラロールから画像またはビデオを選択するためのシステムUIを表示します。また、以下の引数を設定
- mediaTypes: 以下の3つの中からメディアタイプを選択。
- MediaTypeOptions.All (画像と動画)
- MediaTypeOptions.Images (画像のみ)
- MediaTypeOptions.Videos (動画のみ)
- allowEditing: “false” or “true” 画像/動画を選択した後に編集するためのUIを表示するかどうか。
- aspect: [x, y] [x, y]ユーザーが(渡すことによってallowsEditing: true)画像を編集することを許可されている場合に維持するアスペクト比を指定する2つのエントリを持つ配列。iOSではトリミング四角形が常に正方形であるため、これはAndroidにのみ適用されます。
- quality: 0〜1 圧縮の品質を0〜1の範囲で指定します。0は小さいサイズの圧縮を意味し、1は最高品質の圧縮を意味します。
画像:Androidでは、ユーザーは画像をトリミングして回転させることができ、iOSでは単にトリミングします。
ビデオ:iOSユーザーはビデオをトリミングできます。
1 2 3 4 5 6 7 8 9 10 11 12 |
pickImage = async (item) => { let result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ImagePicker.MediaTypeOptions.Images, allowsEditing: true, aspect: [4, 3], quality: 1, }); if (!result.cancelled) { this.setState({ photo: result.uri }); this.onSave(result.uri) } }; |
呼び出した写真の情報を
this.setState({ photo: result.uri });
でthis.state.photoに設定し、これを表示することで写真として表示することができます。