- npm i react-native-vision-camera
- 在AwesomeProject\android\app\src\main\AndroidManifest.xml里添加
<!-- 相机限权--> <uses-permission android:name="android.permission.CAMERA" /> <!-- 麦克风限权--> <uses-permission android:name="android.permission.RECORD_AUDIO" />
- hasPermission(布尔值)获取前设备是否获取限权,requestPermission请求获取限权
import { useCameraPermission } from 'react-native-vision-camera' const { hasPermission, requestPermission } = useCameraPermission() useEffect(() => { //判断是否拥有限权,没有就请求获取 if (!hasPermission) { requestPermission() } }, [hasPermission]) //若不获取限权或未获取,显示加载组件 if (!hasPermission) { return <ActivityIndicator></ActivityIndicator> }
-
获取摄像头
import { useCameraDevice, Camera } from 'react-native-vision-camera' //useCameraDevice获取相机所有设备(front或back)前置后置,后面其他配置官网有 //isActive相机是否处于活跃状态(布尔值),这里先写死 const device = useCameraDevice("back", { physicalDevices: ["ultra-wide-angle-camera"] }) if (!device) { //如果没有就返回 return <Text>Camera device not found</Text> } return ( <View style={{ flex: 1 }}> <Camera style={[styles.abusfell]} device={device} isActive={true}> </Camera> </View> )
-
从应用程序状态来判断相机活跃状态
//需要下载的模块 import { useAppState } from '@react-native-community/hooks' import { useIsFocused } from '@react-navigation/native'; /** * useAppState当应用程序关闭或置于后台时,将在“活动”、“后台”或 *(iOS)“非活动”之一之间更改 * * useIsFocused根据屏幕当前的焦点状态呈现不同的内容,例如导航到新屏幕时, * 使用此挂钩会触发组件的重新渲染 */ const isFocused = useIsFocused() const appState = useAppState() const isActive = isFocused && appState === "active" return ( <View style={{ flex: 1 }}> <Camera style={[styles.abusfell]} device={device} isActive={isActive}> </Camera> </View> )
6.获取相机节点,启用拍照功能
//导入CameraRoll,CameraRoll提供对本地相机胶卷或照片库的访问。
import { CameraRoll } from "@react-native-camera-roll/camera-roll";
const camera = useRef<Camera>(null)
const Tophoto = async () => {
//调用takephoto拍照
const photo = await camera.current?.takePhoto({
//闪光
flash: 'auto'
})
//拍照成功后保存到本地
await CameraRoll.saveAsset(`file://${photo?.path}`), {
type: 'photo',
}
}
return (
<View style={{ flex: 1 }}>
<Camera
ref={camera}
style={[styles.abusfell]}
device={device}
isActive={isActive}
//要拍照,您首先必须启用照片拍摄:
photo={true}
>
</Camera>
//自己设置的拍照按钮
<Pressable onPress={tophoto} style={[styles.test]}></Pressable>
</View>
)
7.完整代码
import { ActivityIndicator, StyleSheet, Text, Pressable, View } from 'react-native'
import React, { useEffect, useRef } from 'react'
import { useCameraPermission, useCameraDevice, Camera } from 'react-native-vision-camera'
import { useAppState } from '@react-native-community/hooks'
import { useIsFocused } from '@react-navigation/native';
import { CameraRoll } from "@react-native-camera-roll/camera-roll";
const index = () => {
const { hasPermission, requestPermission } = useCameraPermission()
const device = useCameraDevice("back", {
physicalDevices: ["ultra-wide-angle-camera"]
})
const camera = useRef<Camera>(null)
/**
* useAppState当应用程序关闭或置于后台时,将在“活动”、“后台”或(iOS)“非活动”之一之间更改
* useIsFocused根据屏幕当前的焦点状态呈现不同的内容,例如导航到新屏幕时,
* 使用此挂钩会触发组件的重新渲染
*/
const isFocused = useIsFocused()
const appState = useAppState()
const isActive = isFocused && appState === "active"
useEffect(() => {
if (!hasPermission) {
requestPermission()
}
}, [hasPermission])
if (!hasPermission) {
return <ActivityIndicator></ActivityIndicator>
}
if (!device) {
return <Text>Camera device not found</Text>
}
const Tophoto = async () => {
const photo = await camera.current?.takePhoto({
flash: 'auto'
})
await CameraRoll.saveAsset(`file://${photo?.path}`), {
type: 'photo',
}
}
return (
<View style={{ flex: 1 }}>
<Camera
ref={camera}
style={[styles.abusfell]}
device={device}
isActive={isActive}
photo={true}
>
</Camera>
<Pressable onPress={Tophoto} style={[styles.test]}></Pressable>
</View>
)
}
export default index
const styles = StyleSheet.create({
abusfell: {
flex: 1
},
test: {
position: "absolute",
alignSelf: "center",
bottom: 10,
width: 75,
height: 75,
backgroundColor: "red",
borderRadius: 75,
opacity: 0.4
}
})
8.若无法显示相机
父容器高度可能为0,给父容器加flex:1,还有App.js里的外层view组件加flex:1,相机本身也要加flex:1,我的按设置是红色