React Native Pick Images From Camera & Gallery Example

Last updated on by Digamber
Today we are going to learn how to pick images from the device’s Camera and Gallery in React Native application. Picking images is an essential task in every developer’s task list. Ordinarily, all the main functionalities can’t be developed by going through picking up images.

In this React Native Image Picker tutorial, we are going to use a very well known library called react-native-image-picker to choose the image from Gallery and Camera.

This library is based on ImagePicker component that lets you use native UI to pick a photo/video from the device library or directly from the camera, and it supports both iOS and Android platforms very smoothly.

Prerequisite

Familiarity with the Following tools, frameworks, and packages are required to get along with this tutorial.

  • IDE
  • NPM
  • Node or yarn
  • Xcode
  • Android Studio
  • React Native
  • React Native CLI
  • react-native image-picker
  • Terminal (macOS, Linux)

Create a New React Native App

This step will guide you on how to get started with React Native, in this step, we will learn to create a brand new React Native project.

Run following command to install react-native-cli on your device.

npm install -g react-native-cli

Run the below command to install a fresh new React Native app from scratch.

create-react-native-app rnImagePicker

Enter inside the app directory.

cd rnImagePicker

When the above process is done, you can checkout the following project structure for your react-native image picker example app.

Create a New React Native App

Configure React Native Image Picker

In this step, we will install react-native-image-picker dependency in the React Native app.

Run command to add the following package.

# 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

Adding Permission for Android to Use Camera & Access Storage

We have to add a few permissions for Android to access Android Camera & Storage.

Let’s understand how to assign permissions for Android devices, and we are about to use Native Camera to pick the image from the Gallery.

Go to React Native Project > android > app > src > debug > AndroidManifest.xml file and include the given below permissions.

<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Here is the final AndroidManifest.xml file.

<?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>

Using React Native Image Picker in React Native App

The React Native Image Picker plugin offers plenty of options to manage the ImagePicker component. We can easily configure the following options in the ImagePicker method.

  • Title
  • Cancel Button Title
  • Take Photo Button Title
  • Choose From Library Button Title
  • Choose Which Library Title
  • Custom Buttons
  • Tint Color
  • Camera Type
  • Media Type
  • Max Width
  • Max Height
  • Quality
  • Video Quality
  • Duration Limit
  • Rotation
  • Allows Editing
  • No Data
  • Storage Options
  • PermissionDenied

First, we have to import the ImagePicker package at the top of the React Native template.

import ImagePicker from 'react-native-image-picker';

Replace the existing code of App.js file with the following code.

// 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'
  }
});

In the above code example we are using ImagePicker component along with the custom options provided by the plugin.

In the given above code, we will initiate the Image Picker by clicking on a “Select File” Button. It will display a popup to “Select Image” with the following options.

  • Take Photo
  • Choose from Library
  • Choose a file from Custom Option

Using React Native Image Picker in React Native App

You must allow permission to access photos, media, and files on your device. Here is the example of Image Picking in React Native from Camera.

Image Picking in React Native from Camera

Launch Camera Directly in React Native App

Accessing Camera directly in the React Native app is not that difficult; we have to access the launchCamera method via the ImagePicker component.

// 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
        });
      }
    });
}

Launch Camera Directly

Directly Launch Image Gallery

Now, we are going to launch Image Gallery directly by using the following code; we need to use the launchImageLibrary method via the ImagePicker component.

// 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
      });
    }
  });
}

Here is the final App.js file example.

// 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'
  }
});

Run React Native App

Run either of the command to run the React Native app on your preferred platform.

To run the app on Android Virtual Device using Android Studio.

react-native run-android

To run the app on iOS Simulator using Xcode.

react-native run-ios

Run React Native App

Conclusion

In this tutorial, we have looked at how to configure and use React Native Image Picker in our React Native Application. This plugin allows us to pick images and videos from the Camera and Gallery.

If you would like to check out the full code of this tutorial, then you can access Github repo here.

Avatar
Digamber

Digamber Rawat is from Uttarakhand, located in northwestern part of India. He is a Full-stack developer by profession and a primary author of this blog.