1--- 2title: Picking an image 3--- 4 5import { SnackInline } from '~/ui/components/Snippet'; 6import Video from '~/components/plugins/Video'; 7import { Terminal } from '~/ui/components/Snippet'; 8 9So far we have been using code from React and React Native in our app. React gives us a nice way to build components and React Native gives us pre-built components that work on iOS, Android, and web — like `View`, `Text`, `TouchableOpacity`. React Native does _not_ provide us with an image picker. For this, we can use an Expo library called [expo-image-picker](/versions/latest/sdk/imagepicker): 10 11> `expo-image-picker` provides access to the system's UI for selecting images and videos from the phone's library or taking a photo with the camera. 12 13## Installing expo-image-picker 14 15To use `expo-image-picker` in our project, we first need to install it. In your project directory, run the following command: 16 17<Terminal cmd={['$ npx expo install expo-image-picker']} /> 18 19This will tell npm (or yarn) to install a version of the `expo-image-picker` library that is compatible with your project. 20 21## Picking an image 22 23With the library installed in our project, we can now actually use it. 24 25<SnackInline label="Image picker" templateId="tutorial/image-picker-log" dependencies={['expo-image-picker']}> 26 27{/* prettier-ignore */} 28```js 29import React from 'react'; 30import { Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; 31/* @info Import the ImagePicker */import * as ImagePicker from 'expo-image-picker';/* @end */ 32 33export default function App() { 34 /* @info Launch the picker and log the result. */ 35 let openImagePickerAsync = async () => { 36 let pickerResult = await ImagePicker.launchImageLibraryAsync(); 37 console.log(pickerResult); 38 } 39 /* @end */ 40 41 return ( 42 <View style={styles.container}> 43 <Image source={{ uri: 'https://i.imgur.com/TkIrScD.png' }} style={styles.logo} /> 44 <Text style={styles.instructions}> 45 To share a photo from your phone with a friend, just press the button below! 46 </Text> 47 <TouchableOpacity onPress={/* @info This function is a bit long so we moved it out to a variable */openImagePickerAsync/* @end */} style={styles.button}> 48 <Text style={styles.buttonText}>Pick a photo</Text> 49 </TouchableOpacity> 50 </View> 51 ); 52} 53``` 54 55</SnackInline> 56 57<br /> 58 59You should see something like this when you run your app and use the picker: 60 61<Video file="tutorial/cli-logs.mp4" /> 62 63> You can see the logs in your expo-cli terminal session or in the browser-based developer tools if you prefer it. To see the logs in Snack, press "Logs" in the footer. 64 65## Using the selected image 66 67Now we will take the data that we get from the image picker and use it to show the selected image in the app. 68 69<SnackInline label="Image picker show image" templateId="tutorial/image-picker-show" dependencies={['expo-image-picker']}> 70 71{/* prettier-ignore */} 72```js 73/* @info Import React to use useState */import React from 'react';/* @end */ 74import { Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; 75import * as ImagePicker from 'expo-image-picker'; 76 77export default function App() { 78 /* @info Initialize a variable to hold our selected image data */const [selectedImage, setSelectedImage] = React.useState(null);/* @end */ 79 80 let openImagePickerAsync = async () => { 81 let pickerResult = await ImagePicker.launchImageLibraryAsync(); 82 /* @info Stop running the function here if the user cancelled the dialog */ 83 if (pickerResult.cancelled === true) { 84 return; 85 }/* @end */ 86 /* @info Store away the picked image uri */setSelectedImage({ localUri: pickerResult.uri });/* @end */ 87 }; 88 89 /* @info Show the selected image if we have one */ 90 if (selectedImage !== null) { 91 return ( 92 <View style={styles.container}> 93 <Image 94 source={{ uri: selectedImage.localUri }} 95 style={styles.thumbnail} 96 /> 97 </View> 98 ); 99 }/* @end */ 100 101 return ( 102 <View style={styles.container}> 103 {/* Our logo, instructions, and picker button are hidden here to keep the example brief */} 104 </View> 105 ); 106} 107 108const styles = StyleSheet.create({ 109 /* Other styles hidden to keep the example brief... */ 110 /* @info We're giving the selected image a fixed width and height */ 111 thumbnail: { 112 width: 300, 113 height: 300, 114 resizeMode: "contain" 115 }/* @end */ 116}); 117``` 118 119</SnackInline> 120 121<br /> 122 123Your app should now look and behave like this: 124 125<Video file="tutorial/picker-show.mp4" /> 126 127> You might expect that because we gave our image an equal width and height it would be a square, but in the above video it's rectangular. This is because of `resizeMode`, an image style property that lets us control how the image is resized to fit the given dimensions. Try switching it from `contain` to `stretch` or `cover` to see other behaviors. 128 129We have made great progress! Up next, [let's make it possible to share the image](/tutorial/sharing). 130