This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.

画像ピッカーを使用する

ページを編集

このチュートリアルでは、Expo Image Picker の使い方を学びます。


React Native は、<View><Text><Pressable> などの組み込みコンポーネントを標準的な構成要素として提供しています。ここで作成するのは、デバイスのメディアギャラリーから画像を選択する機能です。これはコアコンポーネントだけでは実現できないため、この機能をアプリに追加するためにライブラリが必要になります。

Expo SDK のライブラリである expo-image-picker を使用します。

expo-image-picker は、端末のライブラリから画像や動画を選択するためのシステム UI へのアクセスを提供します。

視聴:ユニバーサル Expo アプリで画像ピッカーを使用する
視聴:ユニバーサル Expo アプリで画像ピッカーを使用する

expo-image-picker を使ってデバイスのメディアライブラリから画像を選択する方法を学びます。


1

expo-image-picker をインストールする

expo-image-picker ライブラリをインストールするには、ターミナルで Ctrl + C を押して開発サーバーを停止してから、次のコマンドを実行します。

Terminal
npx expo install expo-image-picker

npx expo install コマンドは、ライブラリをインストールし、package.json のプロジェクトの依存関係に追加します。

ヒント: プロジェクトに新しいライブラリをインストールするときは、ターミナルで Ctrl + C を押して開発サーバーを停止してから、インストールコマンドを実行します。インストールが完了したら、npx expo start を実行して開発サーバーを再起動します。

2

デバイスのメディアライブラリから画像を選択する

expo-image-picker は、デバイスのメディアライブラリから画像や動画を選択するためのシステム UI を表示する launchImageLibraryAsync() メソッドを提供します。前の章で作成した primary テーマのボタンを使ってデバイスのメディアライブラリから画像を選択し、この機能を実装するためにデバイスの画像ライブラリを起動する関数を作成します。

app/(tabs)/index.tsxexpo-image-picker ライブラリをインポートし、Index コンポーネント内に pickImageAsync() 関数を作成します。

app/(tabs)/index.tsx
// ...rest of the import statements remain unchanged import * as ImagePicker from 'expo-image-picker'; export default function Index() { const pickImageAsync = async () => { let result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ['images'], allowsEditing: true, quality: 1, }); if (!result.canceled) { console.log(result); } else { alert('You did not select any image.'); } }; // ...rest of the code remains same }

上記のコードが何をしているのか確認しましょう。

  • launchImageLibraryAsync() は、さまざまなオプションを指定するためのオブジェクトを受け取ります。このオブジェクトは ImagePickerOptions オブジェクトで、メソッドを呼び出すときに渡します。
  • allowsEditingtrue に設定すると、Android と iOS では選択時に画像をトリミングできます。

3

ボタンコンポーネントを更新する

primary ボタンを押したときに、Button コンポーネントから pickImageAsync() 関数を呼び出します。components/Button.tsxButton コンポーネントの onPress プロパティを更新します。

components/Button.tsx
import { StyleSheet, View, Pressable, Text } from 'react-native'; import FontAwesome from '@expo/vector-icons/FontAwesome'; type Props = { label: string; theme?: 'primary'; onPress?: () => void; }; export default function Button({ label, theme, onPress }: Props) { if (theme === 'primary') { return ( <View style={[ styles.buttonContainer, { borderWidth: 4, borderColor: '#ffd33d', borderRadius: 18 }, ]}> <Pressable style={[styles.button, { backgroundColor: '#fff' }]} onPress={onPress}> <FontAwesome name="picture-o" size={18} color="#25292e" style={styles.buttonIcon} /> <Text style={[styles.buttonLabel, { color: '#25292e' }]}>{label}</Text> </Pressable> </View> ); } return ( <View style={styles.buttonContainer}> <Pressable style={styles.button} onPress={() => alert('You pressed a button.')}> <Text style={styles.buttonLabel}>{label}</Text> </Pressable> </View> ); } const styles = StyleSheet.create({ buttonContainer: { width: 320, height: 68, marginHorizontal: 20, alignItems: 'center', justifyContent: 'center', padding: 3, }, button: { borderRadius: 10, width: '100%', height: '100%', alignItems: 'center', justifyContent: 'center', flexDirection: 'row', }, buttonIcon: { paddingRight: 8, }, buttonLabel: { color: '#fff', fontSize: 16, }, });

app/(tabs)/index.tsx で、1 つ目の <Button>onPress プロパティに pickImageAsync() 関数を追加します。

app/(tabs)/index.tsx
import { View, StyleSheet } from 'react-native'; import * as ImagePicker from 'expo-image-picker'; import Button from '@/components/Button'; import ImageViewer from '@/components/ImageViewer'; const PlaceholderImage = require('@/assets/images/background-image.png'); export default function Index() { const pickImageAsync = async () => { let result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ['images'], allowsEditing: true, quality: 1, }); if (!result.canceled) { console.log(result); } else { alert('You did not select any image.'); } }; return ( <View style={styles.container}> <View style={styles.imageContainer}> <ImageViewer imgSource={PlaceholderImage} /> </View> <View style={styles.footerContainer}> <Button theme="primary" label="Choose a photo" onPress={pickImageAsync} /> <Button label="Use this photo" /> </View> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#25292e', alignItems: 'center', }, imageContainer: { flex: 1, }, footerContainer: { flex: 1 / 3, alignItems: 'center', }, });

pickImageAsync() 関数は ImagePicker.launchImageLibraryAsync() を呼び出し、その結果を処理します。launchImageLibraryAsync() メソッドは、選択された画像に関する情報を含むオブジェクトを返します。

result オブジェクトとそのプロパティの例を次に示します。

{ "assets": [ { "assetId": null, "base64": null, "duration": null, "exif": null, "fileName": "ea574eaa-f332-44a7-85b7-99704c22b402.jpeg", "fileSize": 4513577, "height": 4570, "mimeType": "image/jpeg", "rotation": null, "type": "image", "uri": "file:///data/user/0/host.exp.exponent/cache/ExperienceData/%2540anonymous%252FStickerSmash-13f21121-fc9d-4ec6-bf89-bf7d6165eb69/ImagePicker/ea574eaa-f332-44a7-85b7-99704c22b402.jpeg", "width": 2854 } ], "canceled": false }

4

選択した画像を使用する

result オブジェクトには assets 配列があり、その中に選択された画像の uri が含まれています。この値を画像ピッカーから取得して、選択された画像をアプリに表示します。

app/(tabs)/index.tsx ファイルを変更します。

  1. React の useState フックを使って、selectedImage という状態変数を宣言します。この状態変数は選択された画像の URI を保持するために使います。
  2. pickImageAsync() 関数を更新して、画像の URI を selectedImage 状態変数に保存します。
  3. selectedImage をプロパティとして ImageViewer コンポーネントに渡します。
app/(tabs)/index.tsx
import { View, StyleSheet } from 'react-native'; import * as ImagePicker from 'expo-image-picker'; import { useState } from 'react'; import Button from '@/components/Button'; import ImageViewer from '@/components/ImageViewer'; const PlaceholderImage = require('@/assets/images/background-image.png'); export default function Index() { const [selectedImage, setSelectedImage] = useState<string | undefined>(undefined); const pickImageAsync = async () => { let result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ['images'], allowsEditing: true, quality: 1, }); if (!result.canceled) { setSelectedImage(result.assets[0].uri); } else { alert('You did not select any image.'); } }; return ( <View style={styles.container}> <View style={styles.imageContainer}> <ImageViewer imgSource={PlaceholderImage} selectedImage={selectedImage} /> </View> <View style={styles.footerContainer}> <Button theme="primary" label="Choose a photo" onPress={pickImageAsync} /> <Button label="Use this photo" /> </View> </View> ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#25292e', alignItems: 'center', }, imageContainer: { flex: 1, }, footerContainer: { flex: 1 / 3, alignItems: 'center', }, });

プレースホルダー画像の代わりに選択された画像を表示するために、selectedImage プロパティを ImageViewer コンポーネントに渡します。

  1. components/ImageViewer.tsx ファイルを変更して、selectedImage プロパティを受け取れるようにします。
  2. 画像のソースが長くなっているので、imageSource という別の変数に切り出します。
  3. Image コンポーネントの source プロパティの値として imageSource を渡します。
components/ImageViewer.tsx
import { ImageSourcePropType, StyleSheet } from 'react-native'; import { Image } from 'expo-image'; type Props = { imgSource: ImageSourcePropType; selectedImage?: string; }; export default function ImageViewer({ imgSource, selectedImage }: Props) { const imageSource = selectedImage ? { uri: selectedImage } : imgSource; return <Image source={imageSource} style={styles.image} />; } const styles = StyleSheet.create({ image: { width: 320, height: 440, borderRadius: 18, }, });

上記のスニペットでは、Image コンポーネントは条件演算子を使って画像のソースを読み込みます。選択された画像は、プレースホルダー画像のようなローカルアセットではなく、uri 文字列 です。

アプリの状態を確認してみましょう。

このチュートリアルのサンプルアプリで使用されている画像は Unsplash から取得しました。

まとめ

第 4 章:画像ピッカーを使用する

デバイスのメディアライブラリから画像を選択する機能の追加が完了しました。

次の章では、絵文字ピッカーのモーダルコンポーネントを作成する方法を学びます。

次へ:絵文字ピッカーのモーダルを作成する