An In-Depth Guide to Using React Native Image Picker
This tutorial explains how to implement the React Native community module react-native-image-picker, which enables your app to select an image from the user's camera or photo gallery.
6 October 2021
by
Aman Mittal
React Native includes a few options that enable cross-platform apps to select an image from a user’s mobile phone gallery or camera and perform further actions on it. One module that does that is called react-native-image-picker.
This module is maintained by the React Native community, which is one reason why I highly recommend that you use this module. It uses native UI to select a photo or a video from the mobile phone’s library or the camera of that device.
In this tutorial, let us start with the basics of how to integrate this module for both iOS and Android platforms in a React Native app. We’ll then use this module while reviewing some of the common ways to solve different problems when developing an app.
What you need to follow this tutorial
To follow this tutorial, ensure that your dev environment includes the following required packages:
Do note that the following tutorial is going to use the react-native version 0.62.x. Please make sure you’re using a version of React Native above 0.60.x.
For a complete walkthrough on setting up a development environment for React Native, you can go through the official documentation here.
Create a new React Native app
Start by creating a new React Native app. Open a terminal window and execute the following command. I am going to use npx to access the latest React Native CLI version. After the project directory is created, please make sure that you navigate inside the directory.
npx react-native init rnImagePickerExample
# navigate to project directory
cd rnImagePickerExample
# after navigating inside the directory
# install pods for iOS development
npx pod-install
Thanks to awesome open-source developers at Expo, pod-install is a great package that lets you install CocoaPods essential to building and running react-native apps for iOS. You don’t have to dwell inside the ios/ directory and navigate back to the root project. It takes care of that extra step.
Build the app for a specific mobile OS by running either of the two commands as below:
# for iOS
npx react-native run-ios
# for android
npx react-native run-android
Go to the simulator or the device you have connected to run this app and you are going to get a default React Native app.
Cheers! You have created a new React Native app. Let us now get started with this tutorial.
Install and configure react-native-image-picker
Start by running the below command from a terminal window to install the image picker module.
yarn add react-native-image-picker
Once you have done this step, you are going to get a success message in your terminal window. After installing pods, you have to make sure to add permissions. If you do not perform this step, the app might crash or won’t work when using react-native-image-picker.
iOS permissions
For iOS, open /ios/rnImagePickerExample/Info.plist and add the following:
<plist version="1.0">
<dict>
// ...
// add the following
<key>NSPhotoLibraryUsageDescription</key>
<string>$(PRODUCT_NAME) would like access to your photo gallery</string>
<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) would like to use your camera</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>$(PRODUCT_NAME) would like to save photos to your photo gallery</string>
<key>NSMicrophoneUsageDescription</key>
<string>$(PRODUCT_NAME) would like to use your microphone (for videos)</string>
</dict>
</plist>
This is an essential step to make sure you ask for the right permission with the right message, especially if you are looking forward to publishing your app on the store.
CocoaPods installation
Another necessary step to make this app run on iOS is to install CocoaPods for the image picker library we have just installed. After the release of React Native 0.60, the team behind the framework introduced auto-linking so we do not require to link the library. This is “auto-linking” is done by installing pods.
npx pod-install
Make sure to run the build command mentioned in the previous section to run the app again after this step.
Android permissions
Similarly, for Android, you have to add the required permissions in the file /android/app/src/main/AndroidManifest.xml. The first permission is to access the device’s camera, and the second permission is to read or write to storage. This second option for the current demo app allows us to choose the image from the device’s image gallery.
That’s it to install and configure an image picker library in a react native app. For more information check out the official doc here.
Create a simple image picker screen component
The advantage of the React Native Image Picker library is the number of options it provides for you to set and use in your app. The simplest options include changing the title of the picker button or the cancel button, or setting the max height and width of the image picked, but there are some advanced options such as skipBack that are useful when uploading or communicating with a backend service.
Start by creating a simple image picker screen component. Make sure you are at the root location of your project to follow these steps.
Create a new directory called src.
Inside src create a new sub-directory to store all screen components called screens. This is a common convention to keep all screen components inside a React Native app.
Inside the sub-directory create the screen component file called SimpleImagePicker.js as well as a global a style file called Styles.js.
Inside the Styles.js let us define some basic styles using the StyleSheet object from the React Native core API. In the snippet below, you are also going to find some hex color codes that are going to be used throughout this tutorial. Feel free to change these values as per your preference.
Typically you define the types of styles in the above code snippet for a particular screen. But if you are planning to have more than one screen component, you can share styles by creating a global file.
Next, inside SimpleImagePicker.js, start by importing necessary statements as well as styles that you have just created.
Then create a basic component that displays a <Text> inside the functional component SimpleImagePicker().
The state variable imageSource in the above snippet is going to store the value of the URI or the source of the image on the device when a user chooses an image.
To see this screen component in action, one last step left is to modify the App.js file as shown below.
import React from 'react';
import { StatusBar } from 'react-native';
import SimpleImagePicker from './src/screens/SimpleImagePicker';
export default function () {
return (
<>
<StatusBar barStyle='light-content' />
<SimpleImagePicker />
</>
);
}
Go back to a simulator or the physical device you are using to run this app and you are going to be welcomed by the following screen.
How to pick an image?
In this section, let’s create a handler method that is going to allow the user to pick an image. To start, make sure you update the import statements by importing core components from React Native such as TouchableOpacity and Alert. Also, import ImagePicker from the react-native-image-picker library.
Then inside, the screen component creates a new handler method called selectImage(). This method is going to trigger a button on the screen when the user wants to select an image from the device’s library from <TouchableOpacity>.
Inside this method, you are going to add an options object with some primary options like the title of the image picker, the maximum width and height of an image, and setting storage options to not backup an image selected. This options object is used for customization and its not mandatory. This object is also passed as the first argument to the method that actually selects an image.
ImagePicker library has a method called showImagePicker which accepts an object called response as the second argument. This method’s only job is to display the image picker. It shows an alert box when the button is pressed to select an image.
The response object is the most important. It has properties to determine when the user cancels the process of picking an image from the library, or when there is an error in the process of picking an image, or the URI of the local file asset selected by the user, and so on.
We are going to use some of the basic options like did cancel, error, customButton, and uri.
Modify the screen component file as shown below.
import React, { useState } from 'react';
import { View, Text, TouchableOpacity, Alert } from 'react-native';
import { STYLES, COLORS } from './Styles';
import ImagePicker from 'react-native-image-picker';
export default function SimpleImagePicker() {
const [imageSource, setImageSource] = useState(null);
function selectImage() {
let options = {
title: 'You can choose one image',
maxWidth: 256,
maxHeight: 256,
storageOptions: {
skipBackup: true
}
};
ImagePicker.showImagePicker(options, response => {
console.log({ response });
if (response.didCancel) {
console.log('User cancelled photo picker');
Alert.alert('You did not select any image');
} else if (response.error) {
console.log('ImagePicker Error: ', response.error);
} else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
} else {
let source = { uri: response.uri };
console.log({ source });
}
});
}
return (
<View
style={[
STYLES.flex,
STYLES.centerContainer,
{ backgroundColor: COLORS.primaryDark }
]}
>
<Text style={[STYLES.title, { color: COLORS.primaryLight }]}>
Simple Image Picker
</Text>
<TouchableOpacity
onPress={selectImage}
style={[
STYLES.selectButtonContainer,
{ backgroundColor: COLORS.primaryLight }
]}
>
<Text style={STYLES.selectButtonTitle}>Pick an image</Text>
</TouchableOpacity>
</View>
);
}
Also, modify the Styles.js file and add the styles for the new button you have just created.
Now go back to the simulator and you are going to see the new button we have just added is being displayed.
Click the button and there is going to be an alert box pop up.
It gives you the option to select an image from the library or take a photo from the device’s camera (since I am using a simulator, taking a photo is not possible).
At this moment, if you press Cancel, you are going to see another alert box (that we intentionally added to the screen component).
The console statements are also being logged correctly by the metro bundler terminal window. You can verify that as shown in the image below.
To make the alert box disappear, click the button OK. Click the UI button to select an image again, and this time, choose an image from the library.
The first thing it is going to do is to ask for permission. This only happens for the first time when the user is using the app.
Next, select an image in your library as shown below.
After you have selected the image, nothing happens. This is because we still have to write the code to display the image. For now, go to the terminal window and you are going to the response object as well source object with data and information about the image.
If it is not visible or understandable, take a look at the JSON snippet below.
The response object returns details related to the image such as:
data: base64 encoded image data generated
fileSize: the size of the file
fileName: the name of the file name
type: media type such as image/jpeg
uri: which is also the value of the source object
the width and height but with dimensions that we passed as the properties of options object and not the actual image size (which is 500px x 500px).
You can stop the base64 data generation of the image by adding another property called noData: true in the options object, and it will stop generating the base64 if there is no requirement.
let options = {
// rest of the properties remain same
noData: true
};
After adding this property, the new response object won’t have a data field.
The type of the source is essential for the image picker to know. For example, if you only want the user to select an image instead of a video file, then you can set another property called mediaType in the options object.
let options = {
// rest of the properties remain same
mediaType: 'photo' // other values 'video', 'mixed'
};
Setting the value to mixed for this property type will allow the user to select either an image or a video. There are other options on how you can control the user’s input when selecting an image or a video that you can find in the official documentationhereof the image picker library.
Difference between launchImageLibrary() and showImagePicker()
There are separate functions provided by ImagePicker to use for selected methods:
launchCamera(options?, (response) => {})
launchImageLibrary(options?, (response) => {})
Using these methods eliminates the need to show the below alert box to select an option when choosing an image:
These methods are for a direct use case such as when you only want the user to select the image either from the device’s library or take a photo from the device’s camera. If you want to give the user only one option from these two, then you should use one of these methods.
These methods work similarly to showImagePicker. Let’s try one of them. Replace the method showImagePicker() with launchImageLibrary() in the screen component file.
ImagePicker.launchImageLibrary(options, response => {
console.log({ response });
if (response.didCancel) {
console.log('User cancelled photo picker');
Alert.alert('You did not select any image');
} else if (response.error) {
console.log('ImagePicker Error: ', response.error);
} else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
} else {
let source = { uri: response.uri };
console.log({ source });
}
});
Now go back to the device and you’ll notice only one difference. The image library opens as soon as the button from the app is clicked.
The rest of the process is going to be the same.
Display the image
In this section, let’s complete the demo app by displaying the image when the user picks an image from the library. We are also going to display a placeholder image when no image is being selected by the user.
To start, you are going to import the Image from the React Native core API. Then update the handler function by setting the source URI of the image to the state variable image source we defined in the earlier section.
Lastly, you update the JSX of the component.
Here is the complete code snippet for the SimpleImagePicker screen component. We are going to conditionally render when to show the placeholder image from a local asset file and when to display the image that the user has picked.
import React, { useState } from 'react';
import { View, Text, TouchableOpacity, Alert, Image } from 'react-native';
import { STYLES, COLORS } from './Styles';
import ImagePicker from 'react-native-image-picker';
export default function SimpleImagePicker() {
const [imageSource, setImageSource] = useState(null);
function selectImage() {
let options = {
title: 'You can choose one image',
maxWidth: 256,
maxHeight: 256,
noData: true,
mediaType: 'photo',
storageOptions: {
skipBackup: true
}
};
ImagePicker.launchImageLibrary(options, response => {
if (response.didCancel) {
console.log('User cancelled photo picker');
Alert.alert('You did not select any image');
} else if (response.error) {
console.log('ImagePicker Error: ', response.error);
} else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
} else {
let source = { uri: response.uri };
// ADD THIS
setImageSource(source.uri);
}
});
}
return (
<View
style={[
STYLES.flex,
STYLES.centerContainer,
{ backgroundColor: COLORS.primaryDark }
]}
>
<Text style={[STYLES.title, { color: COLORS.primaryLight }]}>
Simple Image Picker
</Text>
{/* ADD THIS */}
<View style={STYLES.imageContainer}>
{imageSource === null ? (
<Image
source={require('../assets/placeholderimage.jpg')}
style={STYLES.imageBox}
resizeMode='contain'
/>
) : (
<Image
source={{ uri: imageSource }}
style={STYLES.imageBox}
resizeMode='contain'
/>
)}
</View>
<TouchableOpacity
onPress={selectImage}
style={[
STYLES.selectButtonContainer,
{ backgroundColor: COLORS.primaryLight }
]}
>
<Text style={STYLES.selectButtonTitle}>Pick an image</Text>
</TouchableOpacity>
</View>
);
}
Go back to the app and when an image is not picked, you are going to see the following result.
When an image is selected, it is going to be displayed instead of the placeholder image.
Conclusion
In this post, you have learned how to configure and implement the react-native-image-picker library to allow a user to pick an image from their device library. When on a physical device, try testing the above code snippet using the device’s Camera. The core functionalities discussed in this post can be customized and advanced further to add more functionalities.
Here is the link to the complete API for the react-native-image-picker library.
The complete code for this tutorial is available at this GitHub repohere.
For more advanced usage of this library with a Crowdbotics app, check out our following tutorials: