Expo

Get Started
API Reference

ImagePicker

expo-image-picker provides access to the system's UI for selecting images and videos from the phone's library or taking a photo with the camera.

Platform Compatibility

Android DeviceAndroid EmulatoriOS DeviceiOS SimulatorWeb

Installation

expo install expo-image-picker

If you're installing this in a bare React Native app, you should also follow these additional installation instructions.

You can configure expo-image-picker using its built-in config plugin if you use config plugins in your project (EAS Build or expo run:[android|ios]). The plugin allows you to configure various properties that cannot be set at runtime and require building a new app binary to take effect.
Are you using the classic build system? (expo build:[android|ios])
Are you using this library in a bare React Native app?
Learn how to configure the native projects in the installation instructions in the expo-image-picker repository.

{
  "expo": {
    "plugins": [
      [
        "expo-image-picker",
        {
          "photosPermission": "The app accesses your photos to let you share them with your friends."
        }
      ]
    ]
  }
}

NameDefaultDescription
photosPermission"Allow $(PRODUCT_NAME) to access your photos"iOS only A string to set the NSPhotoLibraryUsageDescription permission message.
cameraPermission"Allow $(PRODUCT_NAME) to access your camera"iOS only A string to set the NSCameraUsageDescription permission message.
microphonePermission"Allow $(PRODUCT_NAME) to access your microphone"iOS only A string to set the NSMicrophoneUsageDescription permission message.

import React, { useState, useEffect } from 'react';
import { Button, Image, View, Platform } from 'react-native';
import * as ImagePicker from 'expo-image-picker';

export default function ImagePickerExample() {
  const [image, setImage] = useState(null);

  useEffect(() => {
    (async () => {
      if (Platform.OS !== 'web') {
        const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
        if (status !== 'granted') {
          alert('Sorry, we need camera roll permissions to make this work!');
        }
      }
    })();
  }, []);

  const pickImage = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.All,
      allowsEditing: true,
      aspect: [4, 3],
      quality: 1,
    });

    console.log(result);

    if (!result.cancelled) {
      setImage(result.uri);
    }
  };

  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Button title="Pick an image from camera roll" onPress={pickImage} />
      {image && <Image source={{ uri: image }} style={{ width: 200, height: 200 }} />}
    </View>
  );
}
When you run this example and pick an image, you will see the image that you picked show up in your app, and something similar to the following logged to your console:
{
  "cancelled":false,
  "height":1611,
  "width":2148,
  "uri":"file:///data/user/0/host.exp.exponent/cache/cropped1814158652.jpg"
}

Please refer to the with-aws-storage-upload example. Follow Amplify docs to set your project up correctly.

Please refer to the with-firebase-storage-upload example. Make sure you follow the "Using Firebase" docs to set your project up correctly.

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

Asks the user to grant permissions for accessing camera. This does nothing on web because the browser camera is not used.

A promise that resolves to an object of type CameraPermissionResponse.

Asks the user to grant permissions for accessing user's photo. This does nothing on web.

  • writeOnly (boolean) - whether to request write or read and write permissions. Defaults to false.

A promise that resolves to an object of type MediaLibraryPermissionResponse.

Checks user's permissions for accessing camera.

A promise that resolves to an object of type CameraPermissionResponse.

Checks user's permissions for accessing photos.

  • writeOnly (boolean) - whether to get write or read and write permissions. Defaults to false.

A promise that resolves to an object of type MediaLibraryPermissionResponse.

Display the system UI for choosing an image or a video from the phone's library. Requires Permissions.MEDIA_LIBRARY on iOS 10 only. On mobile web, this must be called immediately in a user interaction like a button press, otherwise the browser will block the request without a warning.
Notes for Web: The system UI can only be shown after user activation (e.g. a Button press). Therefore, calling launchImageLibraryAsync in componentDidMount, for example, will not work as intended. The cancelled event will not be returned in the browser due to platform restrictions and inconsistencies across browsers.

  • options (object) --
    A map of options for both:
    • mediaTypes (ImagePicker.MediaTypeOptions) -- Choose what type of media to pick. Defaults to ImagePicker.MediaTypeOptions.Images.
    • allowsEditing (boolean) -- Whether to show a UI to edit the image/video after it is picked. Images: On Android the user can crop and rotate the image and on iOS simply crop it. Videos: On iOS user can trim the video. Defaults to false.
    • allowsMultipleSelection (boolean) -- (Web only) Whether or not to allow selecting multiple media files at once.
    • presentationStyle (ImagePicker.UIImagePickerPresentationStyle) -- (iOS only) Choose presentation style to customize view during picking photo/video. Defaults to ImagePicker.UIImagePickerPresentationStyle.Automatic.
    A map of options for images:
    • aspect (array) -- An array with two entries [x, y] specifying the aspect ratio to maintain if the user is allowed to edit the image (by passing allowsEditing: true). This is only applicable on Android, since on iOS the crop rectangle is always a square.
    • quality (number) -- Specify the quality of compression, from 0 to 1. 0 means compress for small size, 1 means compress for maximum quality.
      Note: If the selected image has been compressed before, the size of the output file may be bigger than the size of the original image.
    • base64 (boolean) -- Whether to also include the image data in Base64 format.
    • exif (boolean) -- Whether to also include the EXIF data for the image.
    Option for videos:
    • videoExportPreset (ImagePicker.VideoExportPreset) -- Available on iOS 11+ only. Specify preset which will be used to compress selected video. Defaults to ImagePicker.VideoExportPreset.Passthrough.
Animated GIFs support If the selected image is an animated GIF, the result image will be an animated GIF too if and only if quality is set to undefined and allowsEditing is set to false. Otherwise compression and/or cropper will pick the first frame of the GIF and return it as the result (on Android the result will be a PNG, on iOS — GIF).

If the user cancelled the picking, returns { cancelled: true }.
Otherwise, this method returns information about the selected media item. When the chosen item is an image, this method returns { cancelled: false, type: 'image', uri, width, height, exif, base64 }; when the item is a video, this method returns { cancelled: false, type: 'video', uri, width, height, duration }.
  • The uri property is a URI to the local image or video file (usable as the source of an Image element, in the case of an image) and width and height specify the dimensions of the media.
  • The exif field is included if the exif option is truthy, and is an object containing the image's EXIF data. The names of this object's properties are EXIF tags and the values are the respective EXIF values for those tags.
  • The base64 property is included if the base64 option is truthy, and is a Base64-encoded string of the selected image's JPEG data. If you prepend this with 'data:image/jpeg;base64,' to create a data URI, you can use it as the source of an Image element; for example: <Image source={{uri: 'data:image/jpeg;base64,' + launchCameraResult.base64}} style={{width: 200, height: 200}} />.
  • The duration property is the length of the video in milliseconds.
Note: Make sure that you handle MainActivity destruction on Android. See ImagePicker.getPendingResultAsync.

Display the system UI for taking a photo with the camera. Requires Permissions.CAMERA. On Android and iOS 10 Permissions.CAMERA_ROLL is also required. On mobile web, this must be called immediately in a user interaction like a button press, otherwise the browser will block the request without a warning.
Notes for Web: The system UI can only be shown after user activation (e.g. a Button press). Therefore, calling launchCameraAsync in componentDidMount, for example, will not work as intended. The cancelled event will not be returned in the browser due to platform restrictions and inconsistencies across browsers.

  • options (object) --
    A map of options:
    • mediaTypes (ImagePicker.MediaTypeOptions) -- Choose what type of media to pick. Defaults to ImagePicker.MediaTypeOptions.Images.
    • allowsEditing (boolean) -- Whether to show a UI to edit the image after it is picked. On Android the user can crop and rotate the image and on iOS simply crop it. Defaults to false.
    • presentationStyle (ImagePicker.UIImagePickerPresentationStyle) -- (iOS only) Choose presentation style to customize view during taking photo/video. Defaults to ImagePicker.UIImagePickerPresentationStyle.Automatic.
    A map of options for images:
    • aspect (array) -- An array with two entries [x, y] specifying the aspect ratio to maintain if the user is allowed to edit the image (by passing allowsEditing: true). This is only applicable on Android, since on iOS the crop rectangle is always a square.
    • quality (number) -- Specify the quality of compression, from 0 to 1. 0 means compress for small size, 1 means compress for maximum quality.
    • base64 (boolean) -- Whether to also include the image data in Base64 format.
    • exif (boolean) -- Whether to also include the EXIF data for the image. On iOS the EXIF data does not include GPS tags in the camera case.
    Option for videos:
    • videoMaxDuration (number) -- Maximum duration, in seconds, for video recording. Setting this to 0 disables the limit. Defaults to 0 (no limit).
      • On iOS, when allowsEditing is set to true, maximum duration is limited to 10 minutes. This limit is applied automatically, if 0 or no value is specified.
      • On Android, effect of this option depends on support of installed camera app.
      • On Web this option has no effect - the limit is browser-dependant.
    • videoExportPreset (ImagePicker.VideoExportPreset) -- Available on iOS 11+ only, but Deprecated. Specify preset which will be used to compress selected video. Defaults to ImagePicker.VideoExportPreset.Passthrough.
    • videoQuality (_ImagePicker.UIImagePickerControllerQualityType_) -- iOS only. Specify the quality of recorded videos. Defaults to ImagePicker.UIImagePickerControllerQualityType.High, which is the highest available for the device.

If the user cancelled the action, the method returns { cancelled: true }.
Otherwise, this method returns information about the selected media item. When the chosen item is an image, this method returns { cancelled: false, type: 'image', uri, width, height, exif, base64 }; when the item is a video, this method returns { cancelled: false, type: 'video', uri, width, height, duration }.
  • The uri property is a URI to the local image or video file (usable as the source of an Image element, in the case of an image) and width and height specify the dimensions of the media.
  • The exif field is included if the exif option is truthy, and is an object containing the image's EXIF data. The names of this object's properties are EXIF tags and the values are the respective EXIF values for those tags.
  • The base64 property is included if the base64 option is truthy, and is a Base64-encoded string of the selected image's JPEG data. If you prepend this with 'data:image/jpeg;base64,' to create a data URI, you can use it as the source of an Image element; for example: <Image source={{uri: 'data:image/jpeg;base64,' + launchCameraResult.base64}} style={{width: 200, height: 200}} />.
  • The duration property is the length of the video in milliseconds.
Note: Make sure that you handle MainActivity destruction on Android. See ImagePicker.getPendingResultAsync.

Android system sometimes kills the MainActivity after the ImagePicker finishes. When this happens, we lost the data selected from the ImagePicker. However, you can retrieve the lost data by calling getPendingResultAsync. You can test this functionality by turning on Don't keep activities in the developer options.

On Android: a promise that resolves to an array of objects of exactly same type as in ImagePicker.launchImageLibraryAsync or ImagePicker.launchCameraAsync if the ImagePicker finished successfully. Otherwise to the array of ImagePicker.ImagePickerErrorResult.
On other platforms: an empty array.

Media typeAccept asset typesPlatforms
MediaTypeOptions.AllImages and videosiOS
MediaTypeOptions.ImagesOnly imagesboth
MediaTypeOptions.VideosOnly videosboth

PresetValueResolutionVideo compression algorithmAudio compression algorithm
VideoExportPreset.Passthrough0UnchangedNoneNone
VideoExportPreset.LowQuality1Depends on the deviceH.264AAC
VideoExportPreset.MediumQuality2Depends on the deviceH.264AAC
VideoExportPreset.HighestQuality3Depends on the deviceH.264AAC
VideoExportPreset.H264_640x4804640 x 480H.264AAC
VideoExportPreset.H264_960x5405960 x 540H.264AAC
VideoExportPreset.H264_1280x72061280 x 720H.264AAC
VideoExportPreset.H264_1920x108071920 x 1080H.264AAC
VideoExportPreset.H264_3840x216083840 x 2160H.264AAC
VideoExportPreset.HEVC_1920x108091920 x 1080HEVCAAC
VideoExportPreset.HEVC_3840x2160103840 x 2160HEVCAAC

PresetValue
UIImagePickerPresentationStyle.FullScreen0
UIImagePickerPresentationStyle.PageSheet1
UIImagePickerPresentationStyle.FormSheet2
UIImagePickerPresentationStyle.CurrentContext3
UIImagePickerPresentationStyle.OverFullScreen5
UIImagePickerPresentationStyle.OverCurrentContext6
UIImagePickerPresentationStyle.Popover7
UIImagePickerPresentationStyle.Automatic-2

PresetValueResolution
UIImagePickerControllerType.High0Highest available
UIImagePickerControllerType.Medium1Depends on the device
UIImagePickerControllerType.Low2Depends on the device
UIImagePickerControllerType.VGA640x4803640 x 480
UIImagePickerControllerType.IFrame1280x72041280 x 720
UIImagePickerControllerType.IFrame960x5405960 x 540

ImagePicker.MediaLibraryPermissionResponse extends PermissionResponse type exported by unimodules-permission-interface and contains additional iOS-specific field:
  • accessPrivileges (string) - Indicates if your app has access to the whole or only part of the photo library. Possible values are:
    • all if the user granted your app access to the whole photo library
    • limited if the user granted your app access only to selected photos (only available on iOS 14.0+)
    • none if user denied or hasn't yet granted the permission

ImagePicker.CameraPermissionResponse alias for PermissionResponse type exported by unimodules-permission-interface.

Object of type ImagePickerErrorResult contains following keys:
  • code (string) - The error code.
  • message (string) - The error message.
  • exception (string | undefined) - The exception which caused the error.

The following permissions are added automatically through the library AndroidManifest.xml.
Android PermissionDescription

Required to be able to access the camera device.

Allows an application to read from external storage.

Allows an application to write to external storage.

The following usage description keys are used by the APIs in this library.
Info.plist KeyDescription

A message that tells the user why the app is requesting access to the device’s microphone.

A message that tells the user why the app is requesting access to the user’s photo library.

A message that tells the user why the app is requesting access to the device’s camera.