React Native Image Picker: Allowing your App to Pick Images from the Gallery and Camera

Reading time: 5 minutes

React Native Image Picker

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.

React Native Image Picker

Step 1: Install react-native-image-picker

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


Step 2: Set the permissions

Once you have completed installation, you must set the permissions to use react-native-image-picker for the image features.



Permissions in an Android environment

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>


Permissions for iOS

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>

Step 3: Use React Native Image Picker

There is a wide variety of options provided by the ImagePicker component. The following options are pretty easy to configure:

  • 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
  • Permission Denied

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.

Step 4: Directly Launch Camera in the React Native app


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

        });

      }

    });

}


Step 5: Directly Launch Image Library in the React Native app

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!

Want to learn more?

If this article was helpful, then you may also find other blogs on React Native interesting. 

Read more on React Native