Almost all the apps today need to pick images from the device’s Gallery and Camera. React Native Image Picker is a module based on an Image Picker component that provides access to the system UI. It has become widely popular since it allows apps to select images from the Gallery or the Camera effectively and straightforwardly.
Below, you will find a step-by-step guide that will lead you through the process of integrating this module into a React Native app.
First things first, you must begin by creating a New React Native Project. Once this is done, you’re ready to go.
First of all, you will need to install react-native-image-picker dependency in the React Native app. Add the package below:
# for npm
npm install react-native-image-picker --save
# for yarn
yarn add react-native-image-picker
# if RN >= 0.60
cd ios && pod install
# if RN < 0.60
react-native link react-native-image-picker
Take into account that in case RN < 0.60, once you have done react-native link react-native-image-picker, you will also have to add the package written above:
cd ios && pod install
To assign permissions for Android devices, go to Project > android > app > src > debug > AndroidManifest.xml and then add the following permissions:
<uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/></
The first one is to access the camera and the second one to read or write the storage.
Now your AndroidManifest.xml file should look like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application android:usesCleartextTraffic="true" tools:targetApi="28" tools:ignore="GoogleAppIndexingWarning" />
</manifest>
Open /ios/rnImagePickerExample/Info.plist and add the permissions below:
<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>
There is a wide variety of options provided by the ImagePicker component. The following options are pretty easy to configure:
First, import the ImagePicker component:
import ImagePicker from ‘react-native-image-picker’;
And then replace the current code of App.js with the following:
// App.js
import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity, Button, Image } from 'react-native';
import ImagePicker from 'react-native-image-picker';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
resourcePath: {},
};
}
selectFile = () => {
var options = {
title: 'Select Image',
customButtons: [
{
name: 'customOptionKey',
title: 'Choose file from Custom Option'
},
],
storageOptions: {
skipBackup: true,
path: 'images',
},
};
ImagePicker.showImagePicker(options, res => {
console.log('Response = ', res);
if (res.didCancel) {
console.log('User cancelled image picker');
} else if (res.error) {
console.log('ImagePicker Error: ', res.error);
} else if (res.customButton) {
console.log('User tapped custom button: ', res.customButton);
alert(res.customButton);
} else {
let source = res;
this.setState({
resourcePath: source,
});
}
});
};
render() {
return (
<View style={styles.container}>
<View style={styles.container}>
<Image
source={{
uri: 'data:image/jpeg;base64,' + this.state.resourcePath.data,
}}
style={{ width: 100, height: 100 }}
/>
<Image
source={{ uri: this.state.resourcePath.uri }}
style={{ width: 200, height: 200 }}
/>
<Text style={{ alignItems: 'center' }}>
{this.state.resourcePath.uri}
</Text>
<TouchableOpacity onPress={this.selectFile} style={styles.button}>
<Text style={styles.buttonText}>Select File</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 30,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#fff'
},
button: {
width: 250,
height: 60,
backgroundColor: '#3740ff',
alignItems: 'center',
justifyContent: 'center',
borderRadius: 4,
marginBottom:12
},
buttonText: {
textAlign: 'center',
fontSize: 15,
color: '#fff'
}
});
Initiate the ImagePicker by clicking on the “Select File” button. Then you will see a screen with the following options: Take Photo, Choose From Library, and Choose a file from Custom Option.
See it below:
When the user opens the app, a screen like the one below asking for permissions will be seen. Permissions must be allowed to access photos, media, and files on the device.
Access the Launch Camera method through the ImagePicker component. To this end, use the code below:
// App.js
cameraLaunch = () => {
let options = {
storageOptions: {
skipBackup: true,
path: 'images',
},
};
ImagePicker.launchCamera(options, (res) => {
console.log('Response = ', res);
if (res.didCancel) {
console.log('User cancelled image picker');
} else if (res.error) {
console.log('ImagePicker Error: ', res.error);
} else if (res.customButton) {
console.log('User tapped custom button: ', res.customButton);
alert(res.customButton);
} else {
const source = { uri: res.uri };
console.log('response', JSON.stringify(res));
this.setState({
filePath: res,
fileData: res.data,
fileUri: res.uri
});
}
});
}
Access the Launch Image Library through the Image Picker component. Use the code below:
// App.js
imageGalleryLaunch = () => {
let options = {
storageOptions: {
skipBackup: true,
path: 'images',
},
};
ImagePicker.launchImageLibrary(options, (res) => {
console.log('Response = ', res);
if (res.didCancel) {
console.log('User cancelled image picker');
} else if (res.error) {
console.log('ImagePicker Error: ', res.error);
} else if (res.customButton) {
console.log('User tapped custom button: ', res.customButton);
alert(res.customButton);
} else {
const source = { uri: res.uri };
console.log('response', JSON.stringify(res));
this.setState({
filePath: res,
fileData: res.data,
fileUri: res.uri
});
}
});
}
The final App.js file example looks like this:
// App.js
import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity, Button, Image } from 'react-native';
import ImagePicker from 'react-native-image-picker';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
resourcePath: {},
};
}
selectFile = () => {
var options = {
title: 'Select Image',
customButtons: [
{
name: 'customOptionKey',
title: 'Choose file from Custom Option'
},
],
storageOptions: {
skipBackup: true,
path: 'images',
},
};
ImagePicker.showImagePicker(options, res => {
console.log('Response = ', res);
if (res.didCancel) {
console.log('User cancelled image picker');
} else if (res.error) {
console.log('ImagePicker Error: ', res.error);
} else if (res.customButton) {
console.log('User tapped custom button: ', res.customButton);
alert(res.customButton);
} else {
let source = res;
this.setState({
resourcePath: source,
});
}
});
};
// Launch Camera
cameraLaunch = () => {
let options = {
storageOptions: {
skipBackup: true,
path: 'images',
},
};
ImagePicker.launchCamera(options, (res) => {
console.log('Response = ', res);
if (res.didCancel) {
console.log('User cancelled image picker');
} else if (res.error) {
console.log('ImagePicker Error: ', res.error);
} else if (res.customButton) {
console.log('User tapped custom button: ', res.customButton);
alert(res.customButton);
} else {
const source = { uri: res.uri };
console.log('response', JSON.stringify(res));
this.setState({
filePath: res,
fileData: res.data,
fileUri: res.uri
});
}
});
}
imageGalleryLaunch = () => {
let options = {
storageOptions: {
skipBackup: true,
path: 'images',
},
};
ImagePicker.launchImageLibrary(options, (res) => {
console.log('Response = ', res);
if (res.didCancel) {
console.log('User cancelled image picker');
} else if (res.error) {
console.log('ImagePicker Error: ', res.error);
} else if (res.customButton) {
console.log('User tapped custom button: ', res.customButton);
alert(res.customButton);
} else {
const source = { uri: res.uri };
console.log('response', JSON.stringify(res));
this.setState({
filePath: res,
fileData: res.data,
fileUri: res.uri
});
}
});
}
render() {
return (
<View style={styles.container}>
<View style={styles.container}>
<Image
source={{
uri: 'data:image/jpeg;base64,' + this.state.resourcePath.data,
}}
style={{ width: 100, height: 100 }}
/>
<Image
source={{ uri: this.state.resourcePath.uri }}
style={{ width: 200, height: 200 }}
/>
<Text style={{ alignItems: 'center' }}>
{this.state.resourcePath.uri}
</Text>
<TouchableOpacity onPress={this.selectFile} style={styles.button} >
<Text style={styles.buttonText}>Select File</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.cameraLaunch} style={styles.button} >
<Text style={styles.buttonText}>Launch Camera Directly</Text>
</TouchableOpacity>
<TouchableOpacity onPress={this.imageGalleryLaunch} style={styles.button} >
<Text style={styles.buttonText}>Launch Image Gallery Directly</Text>
</TouchableOpacity>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 30,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#fff'
},
button: {
width: 250,
height: 60,
backgroundColor: '#3740ff',
alignItems: 'center',
justifyContent: 'center',
borderRadius: 4,
marginBottom:12
},
buttonText: {
textAlign: 'center',
fontSize: 15,
color: '#fff'
}
});
And that’s it. Following the steps detailed above, you should be able to configure and implement React Native Image Picker in a React Native app. Now your app will be able to access the device’s library and take photos!
If this article was helpful, then you may also find other blogs on React Native interesting.
Leave a Reply