Expo ImagePicker
一个库,可提供对系统 UI 的访问,以便从手机库中选择图片和视频或使用相机拍照。
expo-image-picker 提供访问系统界面,以便从手机图库中选择图片和视频,或使用相机拍照。
安装
🌐 Installation
- npx expo install expo-image-pickerIf you are installing this in an existing React Native app, make sure to install expo in your project.
已知问题 iOS
🌐 Known issues
在 iOS 上,当从相机胶卷中选择一张图片(通常是高分辨率)时,裁剪后的图片在某些情况下会给出错误的裁剪矩形值。不幸的是,这个问题出在底层的 UIImagePickerController,这是由 iOS 内置的闭源工具中的一个错误引起的。
🌐 On iOS, when an image (usually of a higher resolution) is picked from the camera roll, the result of the cropped image gives the wrong value for the cropped rectangle in some cases. Unfortunately, this issue is with the underlying UIImagePickerController due to a bug in the closed-source tools built into iOS.
应用配置中的配置
🌐 Configuration in app config
如果你的项目中使用配置插件(连续原生生成(CNG)),你可以使用其内置的 config 插件 配置 expo-image-picker。该插件允许你配置一些无法在运行时设置的属性,这些属性需要构建新的应用二进制文件才能生效。如果你的应用不使用 CNG,那么你需要手动配置该库。
🌐 You can configure expo-image-picker using its built-in config plugin if you use config plugins in your project (Continuous Native Generation (CNG)). The plugin allows you to configure various properties that cannot be set at runtime and require building a new app binary to take effect. If your app does not use CNG, then you'll need to manually configure the library.
默认情况下,expo-image-picker 会在 Android 上添加 RECORD_AUDIO 权限。你可以通过在下面的配置中将 microphonePermission 设置为 false 来移除它。
🌐 By default expo-image-picker will add RECORD_AUDIO permission on Android. You can remove it by setting the microphonePermission to false in the config below.
Example app.json with config plugin
{ "expo": { "plugins": [ [ "expo-image-picker", { "photosPermission": "The app accesses your photos to let you share them with your friends." } ] ] } }
Configurable properties
| Name | Default | Description |
|---|---|---|
photosPermission | "允许 $(PRODUCT_NAME) 访问你的照片" | Only for: iOS 用于设置 |
cameraPermission | "允许 $(PRODUCT_NAME) 访问你的相机" | 用于设置 |
microphonePermission | "允许 $(PRODUCT_NAME) 访问你的麦克风" | 用于设置 |
Are you using this library in an existing React Native app?
如果你没有使用连续原生生成(CNG)或者你是手动使用原生 iOS 项目,那么你需要在你的 ios/[app]/Info.plist 中添加 NSPhotoLibraryUsageDescription、NSCameraUsageDescription 和 NSMicrophoneUsageDescription 键:
🌐 If you're not using Continuous Native Generation (CNG) or you're using a native ios project manually, then you need to add NSPhotoLibraryUsageDescription, NSCameraUsageDescription, and NSMicrophoneUsageDescription keys to your ios/[app]/Info.plist:
<key>NSPhotoLibraryUsageDescription</key> <string>Give $(PRODUCT_NAME) permission to save photos</string> <key>NSCameraUsageDescription</key> <string>Give $(PRODUCT_NAME) permission to access your camera</string> <key>NSMicrophoneUsageDescription</key> <string>Give $(PRODUCT_NAME) permission to use your microphone</string>
用法
🌐 Usage
import { useState } from 'react'; import { Alert, Button, Image, View, StyleSheet } from 'react-native'; import * as ImagePicker from 'expo-image-picker'; export default function ImagePickerExample() { const [image, setImage] = useState<string | null>(null); const pickImage = async () => { // No permissions request is necessary for launching the image library. // Manually request permissions for videos on iOS when `allowsEditing` is set to `false` // and `videoExportPreset` is `'Passthrough'` (the default), ideally before launching the picker // so the app users aren't surprised by a system dialog after picking a video. // See "Invoke permissions for videos" sub section for more details. const permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync(); if (!permissionResult.granted) { Alert.alert('Permission required', 'Permission to access the media library is required.'); return; } let result = await ImagePicker.launchImageLibraryAsync({ mediaTypes: ['images', 'videos'], allowsEditing: true, aspect: [4, 3], quality: 1, }); console.log(result); if (!result.canceled) { setImage(result.assets[0].uri); } }; return ( <View style={styles.container}> <Button title="从相机胶卷中选择一张图片" onPress={pickImage} /> {image && <Image source={{ uri: image }} style={styles.image} />} </View> ); } const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', justifyContent: 'center', }, image: { width: 200, height: 200, }, });
当你运行此示例并选择一个图片时,你将看到你选择的图片显示在应用中,并且控制台中将显示类似的日志:
🌐 When you run this example and pick an image, you will see the image that you picked show up in your app, and a similar log will be shown in the console:
{ "assets": [ { "assetId": "C166F9F5-B5FE-4501-9531", "base64": null, "duration": null, "exif": null, "fileName": "IMG.HEIC", "fileSize": 6018901, "height": 3025, "type": "image", "uri": "file:///data/user/0/host.exp.exponent/cache/cropped1814158652.jpg" "width": 3024 } ], "canceled": false }
调用视频权限 iOS
🌐 Invoke permissions for videos
在 SDK 54 及更高版本中,默认配置保持 allowsEditing 设置为 false,并将 videoExportPreset 设置为 'Passthrough'。这些设置会立即返回原始资源(包括 HEIC 和 AVIF 文件),因为选择器会跳过压缩,但 iOS 需要媒体库权限才能访问原始文件,并在用户选择视频后立即显示权限对话框。
🌐 In SDK 54 and later, the default configuration keeps allowsEditing set to false and videoExportPreset set to 'Passthrough'. These settings return the original asset (including HEIC and AVIF files) instantly because the picker skips compression, but iOS requires media library permission to access the original file and displays a permission dialog immediately after the user selects a video.
为了在选择后避免显示权限对话框,请在打开选择器之前通过 requestMediaLibraryPermissionsAsync 或 useMediaLibraryPermissions 手动请求媒体库权限。
🌐 To avoid showing permissions dialog after selection, manually request media library permissions before opening the picker via requestMediaLibraryPermissionsAsync or useMediaLibraryPermissions.
使用 AWS S3
🌐 With AWS S3
有关如何使用 AWS 存储的示例可以在 with-aws-storage-upload 中找到。
请参阅 Amplify 文档 指南以正确设置你的项目。
🌐 See Amplify documentation guide to set up your project correctly.
使用 Firebase
🌐 With Firebase
有关如何使用 Firebase 存储的示例可以在 with-firebase-storage-upload 中找到。
请参阅 使用 Firebase 指南,以正确设置你的项目。
🌐 See Using Firebase guide to set up your project correctly.
应用接口
🌐 API
import * as ImagePicker from 'expo-image-picker';
Hooks
| Parameter | Type |
|---|---|
| options(optional) | PermissionHookOptions<object> |
Check or request permissions to access the camera.
This uses both requestCameraPermissionsAsync and getCameraPermissionsAsync to interact with the permissions.
[null | PermissionResponse, RequestPermissionMethod<PermissionResponse>, GetPermissionMethod<PermissionResponse>]Example
const [status, requestPermission] = ImagePicker.useCameraPermissions();
| Parameter | Type |
|---|---|
| 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.
[null | MediaLibraryPermissionResponse, RequestPermissionMethod<MediaLibraryPermissionResponse>, GetPermissionMethod<MediaLibraryPermissionResponse>]Example
const [status, requestPermission] = ImagePicker.useMediaLibraryPermissions();
Methods
Checks user's permissions for accessing camera.
Promise<CameraPermissionResponse>A promise that fulfills with an object of type CameraPermissionResponse.
| Parameter | Type | Description |
|---|---|---|
| writeOnly(optional) | boolean | Whether to request write or read and write permissions. Defaults to Default: false |
Checks user's permissions for accessing photos.
Promise<MediaLibraryPermissionResponse>A promise that fulfills with an object of type MediaLibraryPermissionResponse.
Android system sometimes kills the MainActivity after the ImagePicker finishes. When this
happens, we lose the data selected using 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.
Promise<ImagePickerResult | ImagePickerErrorResult | null>- On Android: a promise that resolves to an object of exactly same type as in
ImagePicker.launchImageLibraryAsyncorImagePicker.launchCameraAsyncif theImagePickerfinished successfully. Otherwise, an object of typeImagePickerErrorResult. - On other platforms:
null
| Parameter | Type | Description |
|---|---|---|
| options(optional) | ImagePickerOptions | An 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.
Note: Make sure that you handle
MainActivitydestruction on Android. See ImagePicker.getPendingResultAsync. Notes for Web: The system UI can only be shown after user activation (e.g. aButtonpress). Therefore, callinglaunchCameraAsyncincomponentDidMount, for example, will not work as intended. Thecancelledevent will not be returned in the browser due to platform restrictions and inconsistencies across browsers.
Promise<ImagePickerResult>A promise that resolves to an object with canceled and assets fields.
When the user canceled the action the assets is always null, otherwise it's an array of
the selected media assets which have a form of ImagePickerAsset.
| Parameter | Type | Description |
|---|---|---|
| options(optional) | ImagePickerOptions | An object extended by Default: {} |
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: On Android, if the selected image is an animated GIF, the result image will be an
animated GIF too if and only if quality is explicitly set to 1.0 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, both quality and cropping are supported.
Notes for Web: The system UI can only be shown after user activation (e.g. a
Buttonpress). Therefore, callinglaunchImageLibraryAsyncincomponentDidMount, for example, will not work as intended. Thecancelledevent will not be returned in the browser due to platform restrictions and inconsistencies across browsers.
Promise<ImagePickerResult>A promise that resolves to an object with canceled and assets fields.
When the user canceled the action the assets is always null, otherwise it's an array of
the selected media assets which have a form of ImagePickerAsset.
Asks the user to grant permissions for accessing camera. This does nothing on web because the browser camera is not used.
Promise<CameraPermissionResponse>A promise that fulfills with an object of type CameraPermissionResponse.
| Parameter | Type | Description |
|---|---|---|
| writeOnly(optional) | boolean | Whether to request write or read and write permissions. Defaults to Default: false |
Asks the user to grant permissions for accessing user's photo. This method does nothing on web.
Promise<MediaLibraryPermissionResponse>A promise that fulfills with an object of type MediaLibraryPermissionResponse.
Types
Type: PermissionResponse
Alias for PermissionResponse type exported by expo-modules-core.
Literal Type: string
The shape of the crop area.
Acceptable values are: 'rectangle' | 'oval'
Literal Type: string
The default tab with which the image picker will be opened.
'photos'- the photos/videos tab will be opened.'albums'- the albums tab will be opened.
Acceptable values are: 'photos' | 'albums'
Represents an asset (image or video) returned by the image picker or camera.
| Property | Type | Description |
|---|---|---|
| assetId(optional) | string | null | Only for: Android iOS 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.
|
| base64(optional) | string | null | When the
|
| duration(optional) | number | null | Length of the video in milliseconds or |
| exif(optional) | Record<string, any> | null | Only for: Android iOS The |
| file(optional) | File | Only for: Web The web |
| fileName(optional) | string | null | Preferred filename to use when saving this item. This might be |
| fileSize(optional) | number | File size of the picked image or video, in bytes. |
| height | number | Height of the image or video. |
| mimeType(optional) | string | The MIME type of the selected asset or |
| pairedVideoAsset(optional) | ImagePickerAsset | null | Only for: iOS Contains information about the video paired with the image file. This property is only set when |
| type(optional) | 'image' | 'video' | 'livePhoto' | 'pairedVideo' | The type of the asset.
|
| uri | string | URI to the local image or video file (usable as the source of an |
| width | number | Width of the image or video. |
Type representing canceled pick result.
| Property | Type | Description |
|---|---|---|
| assets | null |
|
| canceled | true | Boolean flag set to |
| Property | Type | Description |
|---|---|---|
| code | string | The error code. |
| exception(optional) | string | The exception which caused the error. |
| message | string | The error message. |
| Property | Type | Description |
|---|---|---|
| allowsEditing(optional) | boolean | Only for: Android iOS 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.
Default: false |
| allowsMultipleSelection(optional) | boolean | Only for: Android iOS 14+ Web Whether or not to allow selecting multiple media files at once.
Default: false |
| aspect(optional) | [number, number] | An array with two entries |
| base64(optional) | boolean | Whether to also include the image data in Base64 format. |
| cameraType(optional) | CameraType | Selects the camera-facing type. The
Default: CameraType.back |
| defaultTab(optional) | DefaultTab | Only for: Android Choose the default tab with which the image picker will be opened. Default: 'photos' |
| exif(optional) | boolean | Only for: Android iOS Whether to also include the EXIF data for the image. On iOS the EXIF data does not include GPS tags in the camera case. |
| legacy(optional) | boolean | Only for: Android Uses the legacy image picker on Android. This will allow media to be selected from outside the users photo library. Default: false |
| mediaTypes(optional) | MediaType | MediaType[] | MediaTypeOptions | Choose what type of media to pick. Default: 'images' |
| orderedSelection(optional) | boolean | Only for: iOS 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.
Default: false |
| preferredAssetRepresentationMode(optional) | UIImagePickerPreferredAssetRepresentationMode | Only for: iOS 14+ Choose preferred asset representation mode to use when loading assets. Default: ImagePicker.UIImagePickerPreferredAssetRepresentationMode.Automatic |
| presentationStyle(optional) | UIImagePickerPresentationStyle | Only for: iOS Choose presentation style to customize view during taking photo/video. Default: ImagePicker.UIImagePickerPresentationStyle.Automatic |
| quality(optional) | number | Only for: Android iOS Specify the quality of compression, from
Default: 1.0 |
| selectionLimit(optional) | number | Only for: Android iOS 14+ The maximum number of items that user can select. Applicable when Default: 0 |
| shape(optional) | CropShape | Only for: Android Specify the shape of the crop area if the user is allowed to edit the image
(by passing Default: rectangle |
| videoExportPreset(optional) | VideoExportPreset |
iOS 11+ Specify preset which will be used to compress selected video. Default: ImagePicker.VideoExportPreset.Passthrough |
| videoMaxDuration(optional) | number | Maximum duration, in seconds, for video recording. Setting this to
|
| videoQuality(optional) | UIImagePickerControllerQualityType | Only for: iOS Specify the quality of recorded videos. Defaults to the highest quality available for the device. Default: ImagePicker.UIImagePickerControllerQualityType.High |
Literal Type: union
Type representing successful and canceled pick result.
Acceptable values are: ImagePickerSuccessResult | ImagePickerCanceledResult
Type representing successful pick result.
| Property | Type | Description |
|---|---|---|
| assets | ImagePickerAsset[] | An array of picked assets. |
| canceled | false | Boolean flag set to |
Extends PermissionResponse type exported by expo-modules-core, containing additional iOS-specific field.
Type: PermissionResponse extended by:
| Property | Type | Description |
|---|---|---|
| accessPrivileges(optional) | 'all' | 'limited' | 'none' | Indicates if your app has access to the whole or only part of the photo library. Possible values are:
|
Literal Type: string
Media types that can be picked by the image picker.
'images'- for images.'videos'- for videos.'livePhotos'- for live photos (iOS only).
When the
livePhotostype is added to the media types array and a live photo is selected, the resultingImagePickerAssetwill contain an unaltered image and thepairedVideoAssetfield will contain a video asset paired with the image. This option will be ignored when theallowsEditingoption is enabled. Due to platform limitations live photos are returned at original quality, regardless of thequalityoption.
When on Android or Web
livePhotostype passed as a media type will be ignored.
Acceptable values are: 'images' | 'videos' | 'livePhotos'
Literal Type: union
Permission expiration time. Currently, all permissions are granted permanently.
Acceptable values are: 'never' | number
Literal Type: union
Acceptable values are: PermissionHookBehavior | Options
An object obtained by permissions get and request functions.
| Property | Type | Description |
|---|---|---|
| canAskAgain | boolean | Indicates 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. |
| expires | PermissionExpiration | Determines time when the permission expires. |
| granted | boolean | A convenience boolean that indicates if the permission is granted. |
| status | PermissionStatus | Determines the status of the permission. |
Enums
Deprecated: To set media types available in the image picker use an array of
MediaTypeinstead.
Picker preferred asset representation mode. Its values are directly mapped to the PHPickerConfigurationAssetRepresentationMode.
UIImagePickerPreferredAssetRepresentationMode.Automatic = "automatic"A mode that indicates that the system chooses the appropriate asset representation.
UIImagePickerPreferredAssetRepresentationMode.Compatible = "compatible"A mode that uses the most compatible asset representation.
Picker presentation style. Its values are directly mapped to the UIModalPresentationStyle.
UIImagePickerPresentationStyle.AUTOMATIC = "automatic"The default presentation style chosen by the system.
On older iOS versions, falls back to WebBrowserPresentationStyle.FullScreen.
UIImagePickerPresentationStyle.CURRENT_CONTEXT = "currentContext"A presentation style where the picker is displayed over the app's content.
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.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.PAGE_SHEET = "pageSheet"A presentation style that partially covers the underlying content.
VideoExportPreset.Passthrough = 0Resolution: Unchanged • Video compression: None • Audio compression: None
VideoExportPreset.LowQuality = 1Resolution: Depends on the device • Video compression: H.264 • Audio compression: AAC
VideoExportPreset.MediumQuality = 2Resolution: Depends on the device • Video compression: H.264 • Audio compression: AAC
VideoExportPreset.HighestQuality = 3Resolution: Depends on the device • Video compression: H.264 • Audio compression: AAC
VideoExportPreset.H264_640x480 = 4Resolution: 640 × 480 • Video compression: H.264 • Audio compression: AAC
VideoExportPreset.H264_960x540 = 5Resolution: 960 × 540 • Video compression: H.264 • Audio compression: AAC
VideoExportPreset.H264_1280x720 = 6Resolution: 1280 × 720 • Video compression: H.264 • Audio compression: AAC
VideoExportPreset.H264_1920x1080 = 7Resolution: 1920 × 1080 • Video compression: H.264 • Audio compression: AAC
VideoExportPreset.H264_3840x2160 = 8Resolution: 3840 × 2160 • Video compression: H.264 • Audio compression: AAC
VideoExportPreset.HEVC_1920x1080 = 9Resolution: 1920 × 1080 • Video compression: HEVC • Audio compression: AAC
权限
🌐 Permissions
安卓
🌐 Android
以下权限会通过库的 AndroidManifest.xml 自动添加。
🌐 The following permissions are added automatically through the library's AndroidManifest.xml.
| Android Permission | Description |
|---|---|
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. |
iOS
该库中的 API 使用以下用法描述键。
🌐 The following usage description keys are used by the APIs in this library.
| Info.plist Key | Description |
|---|---|
| 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. |