Docs-logo

Expo

Get Started
API Reference
Slash-shortcut-icon
Hamburger-icon

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
Status-success-iconStatus-success-iconStatus-success-iconStatus-success-iconStatus-success-icon

Installation

Terminal
→ 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.
Triangle-down-icon
Are you using the classic build system? (expo build:[android|ios])
Triangle-down-icon
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"Only for:
Apple-iconiOS

A string to set the NSPhotoLibraryUsageDescription permission message.
cameraPermission"Allow $(PRODUCT_NAME) to access your camera"Only for:
Apple-iconiOS

A string to set the NSCameraUsageDescription permission message.
microphonePermission"Allow $(PRODUCT_NAME) to access your microphone"Only for:
Apple-iconiOS

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

  const pickImage = async () => {
    // No permissions request is necessary for launching the image library
    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';

NameTypeDescription
options
(optional)
PermissionHookOptions<object>-

Check or request permissions to access the camera. This uses both requestCameraPermissionsAsync and getCameraPermissionsAsync to interact with the permissions.

Example

const [status, requestPermission] = ImagePicker.useCameraPermissions();
  • Undo-icon[null | PermissionResponse, RequestPermissionMethod<PermissionResponse>, GetPermissionMethod<PermissionResponse>]

NameTypeDescription
options
(optional)
PermissionHookOptions<{ writeOnly: boolean }>-

Check or request permissions to access the media library. This uses both requestMediaLibraryPermissionsAsync and getMediaLibraryPermissionsAsync to interact with the permissions.

Example

const [status, requestPermission] = ImagePicker.useMediaLibraryPermissions();

Checks user's permissions for accessing camera.

A promise that fulfills with an object of type CameraPermissionResponse.

Warning-icon
Deprecated. Use getMediaLibraryPermissionsAsync() instead.

NameTypeDescription
writeOnly
(optional)
booleanWhether to request write or read and write permissions. Defaults to false
Default: false

Checks user's permissions for accessing photos.

A promise that fulfills with an object of type MediaLibraryPermissionResponse.

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 ImagePickerErrorResult.
  • On other platforms: an empty array.

NameTypeDescription
options
(optional)
ImagePickerOptionsAn ImagePickerOptions object.
Default: {}

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.

Info-icon
Note: Make sure that you handle MainActivity destruction on Android. See ImagePicker.getPendingResultAsync. 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.

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 }.

NameTypeDescription
options
(optional)
TAn object extended by ImagePickerOptions.

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. 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).

Info-icon
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.

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 }.

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

A promise that fulfills with an object of type CameraPermissionResponse.

Warning-icon
Deprecated. Use requestMediaLibraryPermissionsAsync() instead.

NameTypeDescription
writeOnly
(optional)
booleanWhether to request write or read and write permissions. Defaults to false
Default: false

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

A promise that fulfills with an object of type MediaLibraryPermissionResponse.

An object obtained by getPermissionsAsync and requestPermissionsAsync functions.

NameTypeDescription
canAskAgainbooleanIndicates if user can be asked again for specific permission. If not, one should be directed to the Settings app in order to enable/disable the permission.
expiresPermissionExpirationDetermines time when the permission expires.
grantedbooleanA convenience boolean that indicates if the permission is granted.
statusPermissionStatusDetermines the status of the permission.

Alias for PermissionResponse type exported by expo-modules-core.

Warning-icon
Deprecated. Use ImagePicker.MediaLibraryPermissionResponse instead.

An alias for the MediaLibraryPermissionResponse object.

Generic: T extends ImagePickerOptions | OpenFileBrowserOptions

Type: T extends { allowsMultipleSelection: true } ? ImagePickerMultipleResult : ImagePickerResult

NameTypeDescription
assetId
(optional)
string | nullOnly for:
Apple-iconiOS
Android-iconAndroid

The unique ID that represents the picked image or video, if picked from the library. It can be used by expo-media-library to manage the picked asset.
Info-icon
This might be null when the ID is unavailable or the user gave limited permission to access the media library. On Android, the ID is unavailable when the user selects a photo by directly browsing file system.
base64
(optional)
stringIncluded 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 }}
/>
cancelledbooleanBoolean flag which shows if request was cancelled. If asset data have been returned this should always be false.
duration
(optional)
numberLength of the video in milliseconds.
exif
(optional)
Record<string, any>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.
fileName
(optional)
string | nullOnly for:
Apple-iconiOS

Preferred filename to use when saving this item. This might be null when the name is unavailable or user gave limited permission to access the media library.
fileSize
(optional)
numberOnly for:
Apple-iconiOS

File size of the picked image or video, in bytes.
heightnumberHeight of the image or video.
type
(optional)
'image' | 'video'The type of the asset.
uristringURI 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.
widthnumberWidth of the image or video.

An object returned when the pick action has been cancelled by the user.

NameTypeDescription
cancelledtrue-

NameTypeDescription
codestringThe error code.
exception
(optional)
stringThe exception which caused the error.
messagestringThe error message.

NameTypeDescription
cancelledfalse-
selectedImageInfo[]-

NameTypeDescription
allowsEditing
(optional)
booleanOnly for:
Apple-iconiOS
Android-iconAndroid

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.
Info-icon
Cropping multiple images is not supported - this option is mutually exclusive with allowsMultipleSelection. On iOS, this option is ignored if allowsMultipleSelection is enabled.
Default: false
allowsMultipleSelection
(optional)
booleanOnly for:
Apple-iconiOS 14+
Android-iconAndroid
At-sign-iconWeb

Whether or not to allow selecting multiple media files at once.
Info-icon
Cropping multiple images is not supported - this option is mutually exclusive with allowsEditing. If this option is enabled, then allowsEditing is ignored.
Default: false
aspect
(optional)
[number, number]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.
base64
(optional)
booleanWhether to also include the image data in Base64 format.
exif
(optional)
booleanWhether to also include the EXIF data for the image. On iOS the EXIF data does not include GPS tags in the camera case.
mediaTypes
(optional)
MediaTypeOptionsChoose what type of media to pick.
Default: ImagePicker.MediaTypeOptions.Images
orderedSelection
(optional)
booleanOnly for:
Apple-iconiOS 15+

Whether to display number badges when assets are selected. The badges are numbered in selection order. Assets are then returned in the exact same order they were selected.
Info-icon
Assets should be returned in the selection order regardless of this option, but there is no guarantee that it is always true when this option is disabled.
Default: false
presentationStyle
(optional)
UIImagePickerPresentationStyleOnly for:
Apple-iconiOS

Choose presentation style to customize view during taking photo/video.
Default: ImagePicker.UIImagePickerPresentationStyle.Automatic
quality
(optional)
numberOnly for:
Apple-iconiOS
Android-iconAndroid

Specify the quality of compression, from 0 to 1. 0 means compress for small size, 1 means compress for maximum quality.
Info-icon
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.
Info-icon
Note: On iOS, if a .bmp or .png image is selected from the library, this option is ignored.
Default: 0.2
selectionLimit
(optional)
numberOnly for:
Apple-iconiOS 14+

The maximum number of items that user can select. Applicable when allowsMultipleSelection is enabled. Setting the value to 0 sets the selection limit to the maximum that the system supports.
Default: 0
videoExportPreset
(optional)
VideoExportPreset
Warning-icon
Deprecated. See videoExportPreset in Apple documentation.
Only for:
Apple-iconiOS 11+

Specify preset which will be used to compress selected video.
Default: ImagePicker.VideoExportPreset.Passthrough
videoMaxDuration
(optional)
numberMaximum 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.
videoQuality
(optional)
UIImagePickerControllerQualityTypeOnly for:
Apple-iconiOS

Specify the quality of recorded videos. Defaults to the highest quality available for the device.
Default: ImagePicker.UIImagePickerControllerQualityType.High

Extends PermissionResponse type exported by expo-modules-core and contains additional iOS-specific field.

PermissionResponse extended by:

NameTypeDescription
accessPrivileges
(optional)
'all' | 'limited' | 'none'-

NameTypeDescription
allowsMultipleSelectionbooleanOnly for:
At-sign-iconWeb

Whether or not to allow selecting multiple media files at once.
base64booleanWhether to also include the image data in Base64 format.
capture
(optional)
boolean-
mediaTypes
(optional)
MediaTypeOptionsChoose what type of media to pick.
Default: ImagePicker.MediaTypeOptions.Images

Permission expiration time. Currently, all permissions are granted permamently.

Acceptable values are: 'never', number.

Acceptable values are: PermissionHookBehavior, Options.

MediaTypeOptions.All = "All"

Images and videos.

MediaTypeOptions.Images = "Images"

Only images.

MediaTypeOptions.Videos = "Videos"

Only videos.

PermissionStatus.DENIED = "denied"

User has denied the permission.

PermissionStatus.GRANTED = "granted"

User has granted the permission.

PermissionStatus.UNDETERMINED = "undetermined"

User hasn't granted or denied the permission yet.

UIImagePickerControllerQualityType.High = 0

Highest available resolution.

UIImagePickerControllerQualityType.Medium = 1

Depends on the device.

UIImagePickerControllerQualityType.Low = 2

Depends on the device.

UIImagePickerControllerQualityType.VGA640x480 = 3

640 × 480

UIImagePickerControllerQualityType.IFrame1280x720 = 4

1280 × 720

UIImagePickerControllerQualityType.IFrame960x540 = 5

960 × 540

Only for:
Apple-iconiOS

Picker presentation style. Its values are directly mapped to the UIModalPresentationStyle.

Only for:
Apple-iconiOS 13+

UIImagePickerPresentationStyle.AUTOMATIC = "automatic"

The default presentation style chosen by the system. On older iOS versions, falls back to WebBrowserPresentationStyle.FullScreen.

UIImagePickerPresentationStyle.Automatic = "automatic"
UIImagePickerPresentationStyle.CURRENT_CONTEXT = "currentContext"

A presentation style where the picker is displayed over the app's content.

UIImagePickerPresentationStyle.CurrentContext = "currentContext"
UIImagePickerPresentationStyle.FORM_SHEET = "formSheet"

A presentation style that displays the picker centered in the screen.

UIImagePickerPresentationStyle.FULL_SCREEN = "fullScreen"

A presentation style in which the presented picker covers the screen.

UIImagePickerPresentationStyle.FormSheet = "formSheet"
UIImagePickerPresentationStyle.FullScreen = "fullScreen"
UIImagePickerPresentationStyle.OVER_CURRENT_CONTEXT = "overCurrentContext"

A presentation style where the picker is displayed over the app's content.

UIImagePickerPresentationStyle.OVER_FULL_SCREEN = "overFullScreen"

A presentation style in which the picker view covers the screen.

UIImagePickerPresentationStyle.OverCurrentContext = "overCurrentContext"
UIImagePickerPresentationStyle.OverFullScreen = "overFullScreen"
UIImagePickerPresentationStyle.PAGE_SHEET = "pageSheet"

A presentation style that partially covers the underlying content.

UIImagePickerPresentationStyle.POPOVER = "popover"

A presentation style where the picker is displayed in a popover view.

UIImagePickerPresentationStyle.PageSheet = "pageSheet"
UIImagePickerPresentationStyle.Popover = "popover"

VideoExportPreset.Passthrough = 0

Resolution: Unchanged • Video compression: None • Audio compression: None

VideoExportPreset.LowQuality = 1

Resolution: Depends on the device • Video compression: H.264 • Audio compression: AAC

VideoExportPreset.MediumQuality = 2

Resolution: Depends on the device • Video compression: H.264 • Audio compression: AAC

VideoExportPreset.HighestQuality = 3

Resolution: Depends on the device • Video compression: H.264 • Audio compression: AAC

VideoExportPreset.H264_640x480 = 4

Resolution: 640 × 480 • Video compression: H.264 • Audio compression: AAC

VideoExportPreset.H264_960x540 = 5

Resolution: 960 × 540 • Video compression: H.264 • Audio compression: AAC

VideoExportPreset.H264_1280x720 = 6

Resolution: 1280 × 720 • Video compression: H.264 • Audio compression: AAC

VideoExportPreset.H264_1920x1080 = 7

Resolution: 1920 × 1080 • Video compression: H.264 • Audio compression: AAC

VideoExportPreset.H264_3840x2160 = 8

Resolution: 3840 × 2160 • Video compression: H.264 • Audio compression: AAC

VideoExportPreset.HEVC_1920x1080 = 9

Resolution: 1920 × 1080 • Video compression: HEVC • Audio compression: AAC

VideoExportPreset.HEVC_3840x2160 = 10

Resolution: 3840 × 2160 • Video compression: HEVC • Audio compression: AAC

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.