Core functions for capturing images and videos with the device camera or selecting media from the device's photo library.
Display the system UI for taking a photo with the camera. Requires camera permissions and media library permissions on iOS 10.
/**
* Display the system UI for taking a photo with the camera.
* @param options Configuration options for camera capture
* @returns Promise resolving to ImagePickerResult with captured media or cancellation
*/
function launchCameraAsync(options?: ImagePickerOptions): Promise<ImagePickerResult>;Platform Notes:
getPendingResultAsyncUsage Example:
import * as ImagePicker from 'expo-image-picker';
const takePicture = async () => {
// Check permissions first
const { status } = await ImagePicker.requestCameraPermissionsAsync();
if (status !== 'granted') {
alert('Camera permission is required!');
return;
}
// Launch camera
const result = await ImagePicker.launchCameraAsync({
mediaTypes: 'images',
allowsEditing: true,
aspect: [1, 1],
quality: 0.8,
});
if (!result.canceled) {
console.log('Photo taken:', result.assets[0]);
}
};Display the system UI for choosing media from the phone's library. Requires media library permissions on iOS 10 only.
/**
* Display the system UI for choosing an image or video from the phone's library.
* @param options Configuration options for media selection
* @returns Promise resolving to ImagePickerResult with selected media or cancellation
*/
function launchImageLibraryAsync(options?: ImagePickerOptions): Promise<ImagePickerResult>;Platform Notes:
quality: 1.0 and allowsEditing: falseUsage Examples:
import * as ImagePicker from 'expo-image-picker';
// Single image selection
const pickImage = async () => {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: 'images',
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
if (!result.canceled) {
console.log('Selected image:', result.assets[0].uri);
}
};
// Multiple selection
const pickMultipleImages = async () => {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: 'images',
allowsMultipleSelection: true,
selectionLimit: 5,
quality: 0.8,
});
if (!result.canceled) {
console.log(`Selected ${result.assets.length} images`);
result.assets.forEach((asset, index) => {
console.log(`Image ${index + 1}:`, asset.uri);
});
}
};
// Video selection with editing
const pickVideo = async () => {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: 'videos',
allowsEditing: true,
videoQuality: ImagePicker.UIImagePickerControllerQualityType.Medium,
});
if (!result.canceled) {
const video = result.assets[0];
console.log('Selected video:', video.uri);
console.log('Duration:', video.duration, 'ms');
}
};
// Live Photos (iOS only)
const pickLivePhoto = async () => {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ['images', 'livePhotos'],
quality: 1,
});
if (!result.canceled) {
const asset = result.assets[0];
if (asset.type === 'livePhoto' && asset.pairedVideoAsset) {
console.log('Live photo image:', asset.uri);
console.log('Paired video:', asset.pairedVideoAsset.uri);
}
}
};Retrieve lost data on Android when MainActivity is destroyed after ImagePicker finishes.
/**
* Android system sometimes kills the MainActivity after ImagePicker finishes.
* This function retrieves the lost data from a previous picker operation.
* @returns Promise resolving to the previous ImagePicker result or null
*/
function getPendingResultAsync(): Promise<ImagePickerResult | ImagePickerErrorResult | null>;Platform Notes:
nullUsage Example:
import * as ImagePicker from 'expo-image-picker';
import { AppState } from 'react-native';
// Check for pending result when app becomes active
useEffect(() => {
const handleAppStateChange = async (nextAppState: string) => {
if (nextAppState === 'active') {
const pendingResult = await ImagePicker.getPendingResultAsync();
if (pendingResult && !pendingResult.canceled) {
// Handle the recovered result
console.log('Recovered result:', pendingResult.assets);
}
}
};
const subscription = AppState.addEventListener('change', handleAppStateChange);
return () => subscription?.remove();
}, []);// Main result type
type ImagePickerResult = ImagePickerSuccessResult | ImagePickerCanceledResult;
interface ImagePickerSuccessResult {
canceled: false;
assets: ImagePickerAsset[];
}
interface ImagePickerCanceledResult {
canceled: true;
assets: null;
}
// Error result (from getPendingResultAsync)
interface ImagePickerErrorResult {
code: string;
message: string;
exception?: string;
}
// Asset information
interface ImagePickerAsset {
uri: string;
width: number;
height: number;
type?: 'image' | 'video' | 'livePhoto' | 'pairedVideo';
assetId?: string | null;
fileName?: string | null;
fileSize?: number;
base64?: string | null;
exif?: Record<string, any> | null;
duration?: number | null;
mimeType?: string;
pairedVideoAsset?: ImagePickerAsset | null; // iOS Live Photos
file?: File; // Web only
}