Using Image Picker and Camera in React Native (Expo)

Last updated on May 4, 2021 A Goodman Loading... One comment

This article shows you how to implement an image picker in a React Native project based on Expo SDK.

Example Preview

The app we are going to build together is quite simple. It only contains 2 buttons in the center of the screen. The first one (Select an image) lets you open the device library and select an image and the second one (Open camera) helps you take a picture from the camera. The result will be displayed right below the buttons.

Note:

  • The permission dialog will show up and ask you only once time. If you accidentally deny, you have to go to the Settings section in your iOS or Android emulator and grant access to your Expo app.
  • The iOS simulator doesn’t allow a virtual camera at this time but you can try it with your Android emulator or a real iPhone.

Installing expo-image-picker

Execute the command below to install the expo-image-picker library:

expo install expo-image-picker

The required permission will be automatically configured for you on both iOS and Android so you don’t need to manually do it by yourself (I personally love this so much).

The code

This function used to pick an image from the media library:

const showImagePicker = async () => {
    // Ask the user for the permission to access the media library 
    const permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync();

    if (permissionResult.granted === false) {
      alert("You've refused to allow this appp to access your photos!");
      return;
    }

    const result = await ImagePicker.launchImageLibraryAsync();

    // Explore the result
    console.log(result);

    if (!result.cancelled) {
      setPickedImagePath(result.uri);
      console.log(result.uri);
    }
  }

This function used to take a photo with the camera:

  const openCamera = async () => {
    // Ask the user for the permission to access the camera
    const permissionResult = await ImagePicker.requestCameraPermissionsAsync();

    if (permissionResult.granted === false) {
      alert("You've refused to allow this appp to access your camera!");
      return;
    }

    const result = await ImagePicker.launchCameraAsync();

    // Explore the result
    console.log(result);

    if (!result.cancelled) {
      setPickedImagePath(result.uri);
      console.log(result.uri);
    }
  }

The full code

Replace the default code in your App.js with the following:

// App.js 
import React, { useState } from 'react';
import { View, Text, StyleSheet, Image, Button } from 'react-native';

import * as ImagePicker from 'expo-image-picker';

function App() {
  // The path of the picked image
  const [pickedImagePath, setPickedImagePath] = useState('');

  // This function is triggered when the "Select an image" button pressed
  const showImagePicker = async () => {
    // Ask the user for the permission to access the media library 
    const permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync();

    if (permissionResult.granted === false) {
      alert("You've refused to allow this appp to access your photos!");
      return;
    }

    const result = await ImagePicker.launchImageLibraryAsync();

    // Explore the result
    console.log(result);

    if (!result.cancelled) {
      setPickedImagePath(result.uri);
      console.log(result.uri);
    }
  }

  // This function is triggered when the "Open camera" button pressed
  const openCamera = async () => {
    // Ask the user for the permission to access the camera
    const permissionResult = await ImagePicker.requestCameraPermissionsAsync();

    if (permissionResult.granted === false) {
      alert("You've refused to allow this appp to access your camera!");
      return;
    }

    const result = await ImagePicker.launchCameraAsync();

    // Explore the result
    console.log(result);

    if (!result.cancelled) {
      setPickedImagePath(result.uri);
      console.log(result.uri);
    }
  }

  return (
    <View style={styles.screen}>
      <View style={styles.buttonContainer}>
        <Button onPress={showImagePicker} title="Select an image" />
        <Button onPress={openCamera} title="Open camera" />
      </View>

      <View style={styles.imageContainer}>
        {
          pickedImagePath !== '' && <Image
            source={{ uri: pickedImagePath }}
            style={styles.image}
          />
        }
      </View>
    </View>
  );
}

export default App;

// Kindacode.com
// Just some styles
const styles = StyleSheet.create({
  screen: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  buttonContainer: {
    width: 400,
    flexDirection: 'row',
    justifyContent: 'space-around'
  },
  imageContainer: {
    padding: 30
  },
  image: {
    width: 400,
    height: 300,
    resizeMode: 'cover'
  }
});

Here is my package.json:

{
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "eject": "expo eject"
  },
  "dependencies": {
    "expo": "~41.0.1",
    "expo-status-bar": "~1.0.4",
    "react": "16.13.1",
    "react-dom": "16.13.1",
    "react-native": "https://github.com/expo/react-native/archive/sdk-41.0.0.tar.gz",
    "react-native-web": "~0.13.12",
    "expo-image-picker": "~10.1.4"
  },
  "devDependencies": {
    "@babel/core": "^7.9.0"
  },
  "private": true
}

Conclusion

You’ve learned how to add an image picker to an app managed by Expo SDK. If you’d like to explore more interesting stuff in React Native then take a look at the following articles:

You can also check our React topic page and React Native topic page for the latest tutorials and examples.

Subscribe
Notify of
guest
1 Comment
Inline Feedbacks
View all comments
Foo
Foo
2 months ago

Nice. This helped me a lot

Related Articles