expo-camera
provides a React component that renders a preview for the device's front or back camera. The camera's parameters like zoom, auto focus, white balance and flash mode are adjustable. With the use of Camera
, one can also take photos and record videos that are then saved to the app's cache. Morever, 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 Device | Android Emulator | iOS Device | iOS Simulator | Web |
---|---|---|---|---|
💡Android devices can use one of two available Camera APIs: you can opt-in to usingCamera2
with theuseCamera2Api
prop.
expo install expo-camera
If you're installing this in a bare React Native app, you should also follow these additional installation instructions.
Camera
requires Permissions.CAMERA
. Video recording requires Permissions.AUDIO_RECORDING
.⚠️Only one Camera preview can be active at any given time. If you have multiple screens in your app, you should unmountCamera
components whenever a screen is unfocused.
import React, { useState, useEffect } from 'react'; import { StyleSheet, Text, View, TouchableOpacity } from 'react-native'; import { Camera } from 'expo-camera'; export default function App() { const [hasPermission, setHasPermission] = useState(null); const [type, setType] = useState(Camera.Constants.Type.back); useEffect(() => { (async () => { const { status } = await Camera.requestPermissionsAsync(); setHasPermission(status === 'granted'); })(); }, []); if (hasPermission === null) { return <View />; } if (hasPermission === false) { return <Text>No access to camera</Text>; } return ( <View style={styles.container}> <Camera style={styles.camera} type={type}> <View style={styles.buttonContainer}> <TouchableOpacity style={styles.button} onPress={() => { setType( type === Camera.Constants.Type.back ? Camera.Constants.Type.front : Camera.Constants.Type.back ); }}> <Text style={styles.text}> Flip </Text> </TouchableOpacity> </View> </Camera> </View> ); } %%placeholder-start%%const styles = StyleSheet.create({ ... }); %%placeholder-end%%const styles = StyleSheet.create({ container: { flex: 1, }, camera: { flex: 1, }, buttonContainer: { flex: 1, backgroundColor: 'transparent', flexDirection: 'row', margin: 20, }, button: { flex: 0.1, alignSelf: 'flex-end', alignItems: 'center', }, text: { fontSize: 18, color: 'white', }, });
import { Camera } from 'expo-camera';
import { Camera } from 'expo-camera'; if (await Camera.isAvailableAsync()) { }
['front', 'back']
. This is useful for desktop browsers which only have front-facing cameras.import { Camera } from 'expo-camera'; const types = await Camera.getAvailableCameraTypesAsync();
Camera.Constants.Type
. When Type.front
, use the front-facing camera. When Type.back
, use the back-facing camera. Default: Type.back
.Camera.Constants.FlashMode
. When on
, the flash on your device will turn on when taking a picture, when off
, it won't. Setting to auto
will fire flash if required, torch
turns on flash during the preview. Default: off
.Camera.Constants.AutoFocus
. When on
, auto focus will be enabled, when off
, it wont't and focus will lock as it was in the moment of change but it can be adjusted on some devices via focusDepth
prop.Camera.Constants.WhiteBalance
: auto
, sunny
, cloudy
, shadow
, fluorescent
, incandescent
. If a device does not support any of these values previous one is used.useCamera2Api
is set to true.4:3
, 16:9
, 1:1
. To check if a ratio is supported by the device use getSupportedRatiosAsync
. Default: 4:3
.takePictureAsync
will take. Available sizes can be fetched with getAvailablePictureSizesAsync
.message
.{ type: BarCodeScanner.Constants.BarCodeType, data: string }
, 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.BarCodeScanner
module. Supported settings: [barCodeTypes].<Camera barCodeScannerSettings={{ barCodeTypes: [BarCodeScanner.Constants.BarCodeType.qr], }} />
Note
at the top of this page.Camera.Constants.VideoStabilization.{off, standard, cinematic, auto}
.ref
and invoke them using it.// ... <Camera ref={ref => { this.camera = ref; }} />; // ... snap = async () => { if (this.camera) { let photo = await this.camera.takePictureAsync(); } };
ratio
prop to get a picture with correct dimensions.Note: Make sure to wait for theonCameraReady
callback before calling this method.
true
, camera skips orientation adjustment and returns an image straight from the device's camera. If enabled, quality
option is discarded (processing pipeline is skipped as a whole). Although enabling this option reduces image delivery time significantly, it may cause the image to appear in a wrong orientation in the Image
component (at the time of writing, it does not respect EXIF orientation of the images).Note: Enabling skipProcessing would cause orientation uncertainty.Image
component does not respect EXIF stored orientation information, that means obtained image would be displayed wrongly (rotated by 90°, 180° or 270°). Different devices provide different orientations. For example some Sony Xperia or Samsung devices don't provide correctly oriented images by default. To always obtain correctly oriented image disable skipProcessing option.
{ uri, width, height, exif, base64 }
where uri
is a URI to the local image file on iOS, Android, and a base64 string on web (useable as the source for an Image
element). The width, 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.FileSystem.copyAsync
to make a permanent copy of the image.uri
is a base64 representation of the image because file system URLs are not supported in the browser. The exif
data returned on web is a partial representation of the MediaTrackSettings
, if available.Camera.Constants.VideoQuality['<value>']
, possible values: for 16:9 resolution 2160p
, 1080p
, 720p
, 480p
: Android only
and for 4:3 4:3
(the size is 640x480). If the chosen quality is not available for a device, the highest available is chosen.true
, the recorded video will be flipped along the vertical axis. iOS flips videos recorded with the front camera by default, but you can reverse that back by setting this to true
.uri
property. The Promise is returned if stopRecording
was invoked, one of maxDuration
and maxFileSize
is reached or camera preview is stopped.ratio
prop.['4:3', '1:1']
.ratio
.pictureSize
prop. The list varies across Android devices but is the same for every iOS.takePictureAsync
when preview is paused.Permissions.askAsync(Permissions.CAMERA)
.Permissions.getAsync(Permissions.CAMERA)
.allow="microphone; camera;"
to the iframe element:<iframe src="..." allow="microphone; camera;"> <!-- <Camera /> --> </iframe>