This is documentation for the next SDK version. For up-to-date documentation, see the latest version (SDK 51).
Expo Camera (legacy)A React component that renders a preview for the device's front or back camera.
This is the legacy version of theexpo-camerapackage which will no longer be receiving updates. If you are starting a new project, we recommend using the latest version ofexpo-camera.
expo-camera provides a React component that renders a preview of the device's front or back camera. The camera's parameters such as zoom, auto focus, white balance and flash mode are adjustable. Using Camera, you can take photos and record videos that are saved to the app's cache. The component is also capable of detecting faces and bar codes appearing in the preview. Run the example on your device to see all these features working together.
Android devices can use one of two available Camera APIs: you can opt-in to usingCamera2with theuseCamera2Apiprop.
- npx expo install expo-cameraIf you are installing this in an existing React Native app (bare workflow), start by installing expo in your project. Then, follow the additional instructions as mentioned by library's README under "Installation in bare React Native projects" section.
You can configure expo-camera using its built-in config plugin if you use config plugins in your project (EAS Build or npx 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.
{
"expo": {
"plugins": [
[
"expo-camera",
{
"cameraPermission": "Allow $(PRODUCT_NAME) to access your camera",
"microphonePermission": "Allow $(PRODUCT_NAME) to access your microphone",
"recordAudioAndroid": true
}
]
]
}
}
| Name | Default | Description |
|---|---|---|
cameraPermission | "Allow $(PRODUCT_NAME) to access your camera" | Only for: iOS A string to set the |
microphonePermission | "Allow $(PRODUCT_NAME) to access your microphone" | Only for: iOS A string to set the |
recordAudioAndroid | true | Only for: Android A boolean that determines whether to enable the |
Learn how to configure the native projects in the installation instructions in the expo-camera repository.
Only one Camera preview can be active at any given time. If you have multiple screens in your app, you should unmountCameracomponents whenever a screen is unfocused.
import { Camera, CameraType } from 'expo-camera/legacy';
import { useState } from 'react';
import { Button, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
export default function App() {
const [type, setType] = useState(CameraType.back);
const [permission, requestPermission] = Camera.useCameraPermissions();
if (!permission) {
// Camera permissions are still loading
return <View />;
}
if (!permission.granted) {
// Camera permissions are not granted yet
return (
<View style={styles.container}>
<Text style={{ textAlign: 'center' }}>We need your permission to show the camera</Text>
<Button onPress={requestPermission} title="grant permission" />
</View>
);
}
function toggleCameraType() {
setType(current => (current === CameraType.back ? CameraType.front : CameraType.back));
}
return (
<View style={styles.container}>
<Camera style={styles.camera} type={type}>
<View style={styles.buttonContainer}>
<TouchableOpacity style={styles.button} onPress={toggleCameraType}>
<Text style={styles.text}>Flip Camera</Text>
</TouchableOpacity>
</View>
</Camera>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
},
camera: {
flex: 1,
},
buttonContainer: {
flex: 1,
flexDirection: 'row',
backgroundColor: 'transparent',
margin: 64,
},
button: {
flex: 1,
alignSelf: 'flex-end',
alignItems: 'center',
},
text: {
fontSize: 24,
fontWeight: 'bold',
color: 'white',
},
});
Most browsers support a version of web camera functionality, you can check out the web camera browser support here. Image URIs are always returned as base64 strings because local file system paths are unavailable in the browser.
iframe usageWhen using Chrome versions 64+, if you try to use a web camera in a cross-origin iframe nothing will render. To add support for cameras in your iframe simply add the attribute allow="microphone; camera;" to the iframe element:
<iframe src="..." allow="microphone; camera;">
<!-- <Camera /> -->
</iframe>
import { Camera } from 'expo-camera/legacy';
CameraType: React.Component<CameraProps>
autoFocusOptional • Type: boolean | number | AutoFocus • Default: AutoFocus.on
State of camera auto focus. Use one of AutoFocus.<value>. When AutoFocus.on,
auto focus will be enabled, when AutoFocus.off, it won't and focus will lock as it was in the moment of change,
but it can be adjusted on some devices via focusDepth prop.
barCodeScannerSettingsOptional • Type: BarCodeSettings
Settings exposed by BarCodeScanner module. Supported settings: barCodeTypes.
Example
<Camera
barCodeScannerSettings={{
barCodeTypes: [BarCodeScanner.Constants.BarCodeType.qr],
}}
/>
faceDetectorSettingsOptional • Type: object
A settings object passed directly to an underlying module providing face detection features.
See DetectionOptions in FaceDetector documentation for details.
flashModeOptional • Type: number | FlashMode • Default: FlashMode.off
Camera flash mode. Use one of FlashMode.<value>. When FlashMode.on, the flash on your device will
turn on when taking a picture, when FlashMode.off, it won't. Setting to FlashMode.auto will fire flash if required,
FlashMode.torch turns on flash during the preview.
focusDepthOptional • Type: number • Default: 0
Distance to plane of the sharpest focus. A value between 0 and 1 where: 0 - infinity focus, 1 - focus as close as possible.
For Android this is available only for some devices and when useCamera2Api is set to true.
onBarCodeScannedOptional • Type: (scanningResult: BarCodeScanningResult) => void
Callback that is invoked when a bar code has been successfully scanned. The callback is provided with
an object of the BarCodeScanningResult shape, where the type
refers to the bar code type that was scanned and the data is the information encoded in the bar code
(in this case of QR codes, this is often a URL). See BarCodeScanner.Constants.BarCodeType
for supported values.
onCameraReadyOptional • Type: () => void
Callback invoked when camera preview has been set.
onFacesDetectedOptional • Type: (faces: FaceDetectionResult) => void
Callback invoked with results of face detection on the preview.
See DetectionResult in FaceDetector documentation for more details.
onMountErrorOptional • Type: (event: CameraMountError) => void
Callback invoked when camera preview could not been started.
onResponsiveOrientationChangedOptional • Type: (event: ResponsiveOrientationChanged) => void
Callback invoked when responsive orientation changes. Only applicable if responsiveOrientationWhenOrientationLocked is true
pictureSizeOptional • Type: string
A string representing the size of pictures takePictureAsync will take.
Available sizes can be fetched with getAvailablePictureSizesAsync.
ratioOptional • Type: string • Default: 4:3
A string representing aspect ratio of the preview, eg. 4:3, 16:9, 1:1. To check if a ratio is supported
by the device use getSupportedRatiosAsync.
responsiveOrientationWhenOrientationLockedOptional • Type: boolean
Whether to allow responsive orientation of the camera when the screen orientation is locked (i.e. when set to true
landscape photos will be taken if the device is turned that way, even if the app or device orientation is locked to portrait)
typeOptional • Type: number | CameraType • Default: CameraType.back
Camera facing. Use one of CameraType. When CameraType.front, use the front-facing camera.
When CameraType.back, use the back-facing camera.
useCamera2ApiOptional • Type: boolean
Whether to use Android's Camera2 API. See Note at the top of this page.
videoStabilizationModeOptional • Type: VideoStabilization
The video stabilization mode used for a video recording. Use one of VideoStabilization.<value>.
You can read more about each stabilization type in Apple Documentation.
whiteBalanceOptional • Type: number | WhiteBalance • Default: WhiteBalance.auto
Camera white balance. Use one of WhiteBalance.<value>. If a device does not support any of these values previous one is used.
zoomOptional • Type: number • Default: 0
A value between 0 and 1 being a percentage of device's max zoom. 0 - not zoomed, 1 - maximum zoom.
getAvailableCameraTypesAsync()Returns a list of camera types ['front', 'back']. This is useful for desktop browsers which only have front-facing cameras.
getAvailableVideoCodecsAsync()Queries the device for the available video codecs that can be used in video recording.
A promise that resolves to a list of strings that represents available codecs.
isAvailableAsync()Check whether the current device has a camera. This is useful for web and simulators cases. This isn't influenced by the Permissions API (all platforms), or HTTP usage (in the browser). You will still need to check if the native permission has been accepted.
Promise<boolean>
getAvailablePictureSizesAsync(ratio)| Name | Type | Description |
|---|---|---|
| ratio | string | A string representing aspect ratio of sizes to be returned. |
Get picture sizes that are supported by the device for given ratio.
Promise<string[]>
Returns a Promise that resolves to an array of strings representing picture sizes that can be passed to pictureSize prop.
The list varies across Android devices but is the same for every iOS.
getSupportedRatiosAsync()Get aspect ratios that are supported by the device and can be passed via ratio prop.
Promise<string[]>
Returns a Promise that resolves to an array of strings representing ratios, eg. ['4:3', '1:1'].
pausePreview()Pauses the camera preview. It is not recommended to use takePictureAsync when preview is paused.
Promise<void>
recordAsync(options)| Name | Type | Description |
|---|---|---|
| options (optional) | CameraRecordingOptions | A map of |
Starts recording a video that will be saved to cache directory. Videos are rotated to match device's orientation. Flipping camera during a recording results in stopping it.
Promise<{
uri: string
}>
Returns a Promise that resolves to an object containing video file uri property and a codec property on iOS.
The Promise is returned if stopRecording was invoked, one of maxDuration and maxFileSize is reached or camera preview is stopped.
takePictureAsync(options)| Name | Type | Description |
|---|---|---|
| options (optional) | CameraPictureOptions | An object in form of |
Takes a picture and saves it to app's cache directory. Photos are rotated to match device's orientation
(if options.skipProcessing flag is not enabled) and scaled to match the preview. Anyway on Android it is essential
to set ratio prop to get a picture with correct dimensions.
Note: Make sure to wait for the
onCameraReadycallback before calling this method.
Returns a Promise that resolves to CameraCapturedPicture object, where uri is a URI to the local image file on iOS,
Android, and a base64 string on web (usable as the source for an Image element). The width and height properties specify
the dimensions of the image. base64 is included if the base64 option was truthy, and is a string containing the JPEG data
of the image in Base64--prepend that with 'data:image/jpg;base64,' to get a data URI, which you can use as the source
for an Image element for example. exif is included if the exif option was truthy, and is an object containing EXIF
data for the image--the names of its properties are EXIF tags and their values are the values for those tags.
On native platforms, the local image URI is temporary. Use
FileSystem.copyAsyncto make a permanent copy of the image.
useCameraPermissions(options)| Name | 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] = Camera.useCameraPermissions();
useMicrophonePermissions(options)| Name | Type |
|---|---|
| options (optional) | PermissionHookOptions<object> |
Check or request permissions to access the microphone.
This uses both requestMicrophonePermissionsAsync and getMicrophonePermissionsAsync to interact with the permissions.
[null | PermissionResponse, RequestPermissionMethod<PermissionResponse>, GetPermissionMethod<PermissionResponse>]
Example
const [status, requestPermission] = Camera.useMicrophonePermissions();
Camera.getCameraPermissionsAsync()Checks user's permissions for accessing camera.
A promise that resolves to an object of type PermissionResponse.
Camera.getMicrophonePermissionsAsync()Checks user's permissions for accessing microphone.
A promise that resolves to an object of type PermissionResponse.
Deprecated Use
getCameraPermissionsAsyncorgetMicrophonePermissionsAsyncinstead. Checks user's permissions for accessing camera.
Camera.getPermissionsAsync()Camera.requestCameraPermissionsAsync()Asks the user to grant permissions for accessing camera.
On iOS this will require apps to specify an NSCameraUsageDescription entry in the Info.plist.
A promise that resolves to an object of type PermissionResponse.
Camera.requestMicrophonePermissionsAsync()Asks the user to grant permissions for accessing the microphone.
On iOS this will require apps to specify an NSMicrophoneUsageDescription entry in the Info.plist.
A promise that resolves to an object of type PermissionResponse.
Deprecated Use
requestCameraPermissionsAsyncorrequestMicrophonePermissionsAsyncinstead.
Camera.requestPermissionsAsync()Asks the user to grant permissions for accessing camera.
On iOS this will require apps to specify both NSCameraUsageDescription and NSMicrophoneUsageDescription entries in the Info.plist.
A promise that resolves to an object of type PermissionResponse.
PermissionResponseAn object obtained by permissions get and request functions.
PermissionResponse Properties
| Name | 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. |
BarCodeBounds| Name | Type | Description |
|---|---|---|
| origin | BarCodePoint | The origin point of the bounding box. |
| size | BarCodeSize | The size of the bounding box. |
BarCodePointType: Point
These coordinates are represented in the coordinate space of the camera source (e.g. when you are using the camera view, these values are adjusted to the dimensions of the view).
BarCodeScanningResult| Name | Type | Description |
|---|---|---|
| bounds | BarCodeBounds | The BarCodeBounds object.
|
| cornerPoints | BarCodePoint[] | Corner points of the bounding box.
|
| data | string | The parsed information encoded in the bar code. |
| type | string | The barcode type. |
CameraCapturedPicture| Name | Type | Description |
|---|---|---|
| base64 (optional) | string | A Base64 representation of the image. |
| exif (optional) | Partial<MediaTrackSettings> | any | On Android and iOS this object may include various fields based on the device and operating system.
On web, it is a partial representation of the |
| height | number | Captured image height. |
| uri | string | On web, the value of |
| width | number | Captured image width. |
CameraPictureOptions| Name | Type | Description |
|---|---|---|
| additionalExif (optional) | Record<string, any> | Only for: Android iOS Additional EXIF data to be included for the image. Only useful when |
| base64 (optional) | boolean | Whether to also include the image data in Base64 format. |
| exif (optional) | boolean | Whether to also include the EXIF data for the image. |
| imageType (optional) | ImageType | - |
| isImageMirror (optional) | boolean | - |
| onPictureSaved (optional) | (picture: CameraCapturedPicture) => void | A callback invoked when picture is saved. If set, the promise of this method will resolve immediately with no data after picture is captured. The data that it should contain will be passed to this callback. If displaying or processing a captured photo right after taking it is not your case, this callback lets you skip waiting for it to be saved. |
| quality (optional) | number | Specify the compression quality from |
| scale (optional) | number | - |
| skipProcessing (optional) | boolean | If set to
|
CameraRecordingOptions| Name | Type | Description |
|---|---|---|
| codec (optional) | VideoCodec | Only for: iOS This option specifies what codec to use when recording the video. See |
| maxDuration (optional) | number | Maximum video duration in seconds. |
| maxFileSize (optional) | number | Maximum video file size in bytes. |
| mirror (optional) | boolean | Only for: iOS If |
| mute (optional) | boolean | If present, video will be recorded with no sound. |
| quality (optional) | number | string | Specify the quality of recorded video. Use one of |
| videoBitrate (optional) | number | Only for: Android Only works if |
FaceDetectionResult| Name | Type | Description |
|---|---|---|
| faces | object[] | Array of objects representing results of face detection.
See |
PermissionExpirationLiteral Type: multiple types
Permission expiration time. Currently, all permissions are granted permanently.
Acceptable values are: 'never' | number
PermissionHookOptionsLiteral Type: multiple types
Acceptable values are: PermissionHookBehavior | Options
portraitCameraOrientation.portrait = 1portraitUpsideDownCameraOrientation.portraitUpsideDown = 2landscapeLeftCameraOrientation.landscapeLeft = 3landscapeRightCameraOrientation.landscapeRight = 4autoFlashMode.auto = "auto"offFlashMode.off = "off"onFlashMode.on = "on"torchFlashMode.torch = "torch"UNDETERMINEDPermissionStatus.UNDETERMINED = "undetermined"User hasn't granted or denied the permission yet.
AppleProRes4444VideoCodec.AppleProRes4444 = "ap4h"AppleProRes422VideoCodec.AppleProRes422 = "apcn"H264VideoCodec.H264 = "avc1"HEVCVideoCodec.HEVC = "hvc1"JPEGVideoCodec.JPEG = "jpeg"1080pVideoQuality.1080p = "1080p"2160pVideoQuality.2160p = "2160p"4:3VideoQuality.4:3 = "4:3"480pVideoQuality.480p = "480p"720pVideoQuality.720p = "720p"VideoStabilizationThis option specifies the stabilization mode to use when recording a video.
VideoStabilization Values
autoVideoStabilization.auto = "auto"cinematicVideoStabilization.cinematic = "cinematic"offVideoStabilization.off = "off"standardVideoStabilization.standard = "standard"autoWhiteBalance.auto = "auto"This package automatically adds the CAMERA permission to your app. If you want to record videos with audio, you have to include the RECORD_AUDIO in your app.json inside the expo.android.permissions array.
| Android Permission | Description |
|---|---|
Required to be able to access the camera device. | |
Allows an application to record audio. |
The following usage description keys are used by this library:
| Info.plist Key | Description |
|---|---|
| A message that tells the user why the app is requesting access to the device’s camera. | |
| A message that tells the user why the app is requesting access to the device’s microphone. |