@ohmi/react-native-camera
v4.2.1-1.4.2
Published
A Camera component for React Native. Also reads barcodes.
Downloads
27
Readme
模板版本:v0.2.2
[!TIP] Gitee 地址
介绍
本项目基于react-native-camera开发。
安装与使用
请到三方库的 Releases 发布地址查看配套的版本信息:@ohmi/react-native-camera Releases 。对于未发布到npm的旧版本,请参考安装指南安装tgz包。
进入到工程目录并输入以下命令:
npm
npm install @ohmi/react-native-camerayarn
yarn add @ohmi/react-native-camera下面的代码展示了这个库的基本使用场景:
[!WARNING] 使用时 import 的库名不变。
photo example
import React, {useState, useRef} from 'react';
import {StyleSheet, Text, View, Button, Image} from 'react-native';
import {RNCamera} from 'react-native-camera';
export const PhotoDemo = () => {
const cameraRef = useRef(null);
const [capturedImage, setCapturedImage] = useState(null);
const takePicture = async () => {
if (cameraRef.current) {
try {
const options = {quality: 0.5, base64: false};
const data = await cameraRef.current.takePictureAsync(options);
setCapturedImage(data.uri);
} catch (error) {
console.error('拍照出错:', error);
}
}
};
return (
<View style={styles.container}>
{capturedImage ? (
<Image source={{uri: capturedImage}} style={styles.capturedImage} />
) : (
<RNCamera
ref={cameraRef}
style={styles.preview}
type={RNCamera.Constants.Type.back}
flashMode={RNCamera.Constants.FlashMode.off}
/>
)}
<Button title="拍照" onPress={takePicture} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
preview: {
width: 300,
height: 400,
marginBottom: 20,
},
capturedImage: {
width: 300,
height: 400,
marginBottom: 20,
},
});video example
import React, {useState, useRef} from 'react';
import {StyleSheet, Text, View, Button} from 'react-native';
import {RNCamera} from 'react-native-camera';
export const VideoDemo = () => {
const cameraRef = useRef(null);
const [isRecording, setIsRecording] = useState(false);
const [isPaused, setIsPaused] = useState(false);
const [videoUri, setVideoUri] = useState(null);
const startRecording = async () => {
if (cameraRef.current) {
try {
const options = {quality: RNCamera.Constants.VideoQuality['720p']};
const videoRecordPromise = cameraRef.current.recordAsync(options);
if (videoRecordPromise) {
setIsRecording(true);
const data = await videoRecordPromise;
setVideoUri(data.uri);
setIsRecording(false);
}
} catch (error) {
console.error('录制视频出错:', error);
}
}
};
const stopRecording = () => {
if (cameraRef.current) {
cameraRef.current.stopRecording();
setIsRecording(false);
}
};
const pauseRecording = () => {
if (cameraRef.current) {
cameraRef.current.pausePreview();
setIsPaused(true);
}
};
const resumeRecording = () => {
if (cameraRef.current) {
cameraRef.current.resumePreview();
setIsPaused(false);
}
};
return (
<View style={styles.container}>
<RNCamera
ref={cameraRef}
style={styles.preview}
type={RNCamera.Constants.Type.back}
flashMode={RNCamera.Constants.FlashMode.off}
captureAudio={true}
onRecordingStart={()=>{}}
/>
<View style={styles.buttonContainer}>
{!isRecording && <Button title="开始录制" onPress={startRecording} />}
{isRecording && !isPaused && (
<Button title="暂停录制" onPress={pauseRecording} />
)}
{isRecording && isPaused && (
<Button title="恢复录制" onPress={resumeRecording} />
)}
{isRecording && <Button title="停止录制" onPress={stopRecording} />}
</View>
{videoUri && (
<Text style={styles.videoUriText}>视频保存路径: {videoUri}</Text>
)}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
preview: {
width: 300,
height: 400,
marginBottom: 20,
},
buttonContainer: {
flexDirection: 'row',
justifyContent: 'space-around',
width: '100%',
backgroundColor: '#000',
padding: 4,
},
videoUriText: {
textAlign: 'center',
},
videoPlayer: {
width: 300,
height: 400,
marginBottom: 20,
},
});Link
目前 HarmonyOS 暂不支持 AutoLink,所以 Link 步骤需要手动配置。
首先需要使用 DevEco Studio 打开项目里的 HarmonyOS 工程 harmony
1.在工程根目录的 oh-package.json 添加 overrides字段
{
...
"overrides": {
"@rnoh/react-native-openharmony" : "./react_native_openharmony"
}
}2.引入原生端代码
目前有两种方法:
- 通过 har 包引入(在 IDE 完善相关功能后该方法会被遗弃,目前首选此方法);
- 直接链接源码。
方法一:通过 har 包引入 (推荐)
[!TIP] har 包位于三方库安装路径的
harmony文件夹下。
打开 entry/oh-package.json5,添加以下依赖
"dependencies": {
"@rnoh/react-native-openharmony": "file:../react_native_openharmony",
"@ohmi/react-native-camera": "file:../../node_modules/@ohmi/react-native-camera/harmony/camera.har"
}点击右上角的 sync 按钮
或者在终端执行:
cd entry
ohpm install方法二:直接链接源码
[!TIP] 如需使用直接链接源码,请参考直接链接源码说明
3.配置 CMakeLists 和引入 RTNCameraPackage
打开 entry/src/main/cpp/CMakeLists.txt,添加:
project(rnapp)
cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_SKIP_BUILD_RPATH TRUE)
set(RNOH_APP_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set(NODE_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../node_modules")
+ set(OH_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/../../../oh_modules")
set(RNOH_CPP_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../react-native-harmony/harmony/cpp")
set(LOG_VERBOSITY_LEVEL 1)
set(CMAKE_ASM_FLAGS "-Wno-error=unused-command-line-argument -Qunused-arguments")
set(CMAKE_CXX_FLAGS "-fstack-protector-strong -Wl,-z,relro,-z,now,-z,noexecstack -s -fPIE -pie")
set(WITH_HITRACE_SYSTRACE 1) # for other CMakeLists.txt files to use
add_compile_definitions(WITH_HITRACE_SYSTRACE)
add_subdirectory("${RNOH_CPP_DIR}" ./rn)
# RNOH_BEGIN: manual_package_linking_1
add_subdirectory("../../../../sample_package/src/main/cpp" ./sample-package)
+ add_subdirectory("${OH_MODULES}/@ohmi/react-native-camera/src/main/cpp" ./camera)
# RNOH_END: manual_package_linking_1
file(GLOB GENERATED_CPP_FILES "./generated/*.cpp")
add_library(rnoh_app SHARED
${GENERATED_CPP_FILES}
"./PackageProvider.cpp"
"${RNOH_CPP_DIR}/RNOHAppNapiBridge.cpp"
)
target_link_libraries(rnoh_app PUBLIC rnoh)
# RNOH_BEGIN: manual_package_linking_2
target_link_libraries(rnoh_app PUBLIC rnoh_sample_package)
+ target_link_libraries(rnoh_app PUBLIC rnoh_camera)
# RNOH_END: manual_package_linking_2打开 entry/src/main/cpp/PackageProvider.cpp,添加:
#include "RNOH/PackageProvider.h"
#include "generated/RNOHGeneratedPackage.h"
#include "SamplePackage.h"
+ #include "RTNCameraPackage.h"
using namespace rnoh;
std::vector<std::shared_ptr<Package>> PackageProvider::getPackages(Package::Context ctx) {
return {
std::make_shared<RNOHGeneratedPackage>(ctx),
std::make_shared<SamplePackage>(ctx),
+ std::make_shared<RTNCameraPackage>(ctx),
};
}4.在 ArkTs 侧引入 RTNCameraView 组件
找到 function buildCustomRNComponent(),一般位于 entry/src/main/ets/pages/index.ets 或 entry/src/main/ets/rn/LoadBundle.ets,添加:
...
+ import { RTNCameraView } from "@ohmi/react-native-camera";
@Builder
export function buildCustomRNComponent(ctx: ComponentBuilderContext) {
...
+ if (ctx.componentName === RTNCameraView.NAME) {
+ RTNCameraView({
+ ctx: ctx.rnComponentContext,
+ tag: ctx.tag,
+ })
+ }
...
}
...在entry/src/main/ets/pages/index.ets中,如果当前文件中存在arkTsComponentNames数组(后续版本新增内容),则需要在其中追加:RTNCameraView.NAME;
...
const arkTsComponentNames: Array<string> = [..., RTNCameraView.NAME];
...5.在 ArkTs 侧引入 RTNCameraPackage
打开 entry/src/main/ets/RNPackagesFactory.ts,添加:
...
+ import { RTNCameraPackage } from "@ohmi/react-native-camera/ts";
export function createRNPackages(ctx: RNPackageContext): RNPackage[] {
return [
new SamplePackage(ctx),
+ new RTNCameraPackage(ctx),
];
}6.运行
点击右上角的 sync 按钮
或者在终端执行:
cd entry
ohpm install然后编译、运行即可。
约束与限制
兼容性
本文档内容基于以下版本验证通过:
RNOH:0.72.50; SDK:5.0.2.126 ; IDE:DevEco Studio 5.0.7.210; ROM:5.0.0.135;
权限要求
以下权限中有system_basic 权限,而默认的应用权限是 normal ,只能使用 normal 等级的权限,所以可能会在安装hap包时报错9568289,请参考 文档 修改应用等级为 system_basic
在 entry 目录下的module.json5中添加权限
打开 entry/src/main/module.json5,添加:
...
"requestPermissions": [
+ {
+ "name": "ohos.permission.CAMERA",
+ "reason": "$string:camera_reason",
+ "usedScene": {
+ "abilities": [
+ "EntryAbility"
+ ],
+ "when":"inuse"
+ }
+ },
+ {
+ "name": "ohos.permission.MICROPHONE",
+ "reason": "$string:microphone_reason",
+ "usedScene": {
+ "abilities": [
+ "EntryAbility"
+ ],
+ "when":"inuse"
+ }
+ },
]在 entry 目录下添加申请以上权限的原因
打开 entry/src/main/resources/base/element/string.json,添加:
...
{
"string": [
+ {
+ "name": "camera_reason",
+ "value": "使用相机"
+ },
+ {
+ "name": "microphone_reason",
+ "value": "使用麦克风"
+ },
]
}鸿蒙属性要求
onRecordingStart:开始录制视频的回调,(由于鸿蒙平台差异,如果是视频录制模式,此参数必填,拍照模式不用填写),可参照视频录制功能demo实现。
属性
[!TIP] "Platform"列表示该属性在原三方库上支持的平台。
[!TIP] "HarmonyOS Support"列为 yes 表示 HarmonyOS 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。
| Name | Description | Type | Required | Platform | HarmonyOS Support |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | -------- | -------- | ----------------- |
| zoom | This property specifies the zoom value of the camera. Ranges from 0 to 1. Default to 0 | number | no | All | yes |
| maxZoom | The maximum zoom value of the camera. Defaults to 0. | number | no | All | yes |
| type | This property defines which camera on the phone the component is using. Possible values: | 'front'/'back' | no | All | yes |
| focusMode | Camera focus mode. Default: on | 'on'/'off' | no | All | yes |
| zoomMode | Enable the pinch to zoom gesture. Default: on | 'on'/'off' | no | All | yes |
| zoom | Control the zoom. Default: 1.0 | number | no | All | yes |
| maxZoom | Maximum zoom allowed (but not beyond what camera allows). Default: undefined (camera default max) | number | no | All | yes |
| cameraId | For selecting from multiple cameras on Android devices. See 2492 for more info. Can be retrieved with | string | no | All | yes |
| flashMode | Determines the state of the camera flash. Has the following possible states | string | no | All | yes |
| ratio | A string representing the camera ratio in the format 'height:width'. Default is "4:3". | string | no | All | yes |
| pictureSize | This prop has a different behaviour for Android and iOS and should rarely be set. | string | no | All | yes |
| autoFocusPointOfInterest | Setting this property causes the auto focus feature of the camera to attempt to focus on the part of the image at this coordiate. | object | no | all | yes |
| captureAudio | Android only. Enable or disable the shutter sound when capturing a photo. Default: true | Boolean | no | Android | yes |
| ratioOverlay | Show a guiding overlay in the camera preview for the selected ratio. Does not crop image as of v9.0. Example: '16:9' | String | no | iOS | yes |
| ratioOverlayColor | Any color with alpha. Default: '#ffffff77' | String | no | All | yes |
| resetFocusTimeout | Dismiss tap to focus after this many milliseconds. Default 0 (disabled). Example: 5000 is 5 seconds. | Number | no | All | yes |
| keepAudioSession | (iOS Only) When the camera is unmounted, it will release any audio session it acquired (if captureAudio=true) so other media can continue playing. However, this might not be always desirable (e.g., if video is played afterwards) and can be disabled by setting it to true. Setting this to true, means your app will not release the audio session. Note: other apps might still "steal" the audio session from your app. | Boolean | no | iOS | no |
| focusDepth | Manually set camera focus. Only works with autoFocus off. The value 0 is minimum focus depth, 1 is maximum focus depth. For a medium focus depth, for example, you could use 0.5. | number | no | all | no |
| whiteBalance | A camera’s white balance setting allows you to control the color temperature in your photos by cooling down or warming up the colors. | string | no | all | yes |
| exposure | Value: float from 0 to 1.0, or -1 (default) for auto. | string | no | all | yes |
| useNativeZoom | Boolean to turn on native pinch to zoom. Works with the maxZoom property on iOS. | Boolean | no | iOS | yes |
| permissionDialogTitle | Android Permissions dialog title | sting | no | android | no |
| permissionDialogMessage | Android Permissions dialog message | string | no | android | no |
| androidRecordAudioPermissionOptions | Android recording permission options | sting | no | android | no |
| androidCameraPermissionOptions | Android camera permission options | sting | no | android | no |
| notAuthorizedView | By default a Camera not authorized message will be displayed when access to the camera has been denied, if set displays the passed react element instead of the default one. | element | no | all | yes |
| pendingAuthorizationView | By default a will be displayed while the component is waiting for the user to grant/deny access to the camera, if set displays the passed react element instead of the default one. | element | no | all | yes |
| rectOfInterest | An {x: , y:, width:, height: } object which defines the rect of interst as normalized coordinates from (0,0) top left corner to (1,1) bottom right corner. | object | no | all | no |
| cameraViewDimensions | An {width:, height: } object which defines the width and height of the cameraView. This prop is used to adjust the effect of Aspect Raio for rectOfInterest area on Android | object | no | android | no |
| playSoundOnCapture | Boolean to turn on or off the camera's shutter sound (default false). Note that in some countries, the shutter sound cannot be turned off. | boolean | no | all | yes |
| playSoundOnRecord | Boolean to turn on or off the camera's record sound (default false) | boolean | no | all | yes |
| videoStabilizationMode | The video stabilization mode used for a video recording. | string | no | all | no |
| defaultVideoQuality | This option specifies the quality of the video to be taken. The possible values are:2160p,1080p,720p,480p,4:3,288p | string | no | all | yes |
| barCodeTypes | An array of barcode types to search for. Defaults to all types listed above. No effect if onBarCodeRead is undefined. | string | no | all | yes |
| googleVisionBarcodeType | Like barCodeTypes, but applies to the Firebase MLKit barcode detector. | string | no | all | partially |
| googleVisionBarcodeMode | Google Visual bar code pattern | string | no | all | no |
| detectedImageInEvent | When detectedImageInEvent is false (default), onBarCodeRead / onBarcodesDetected only gives metadata, but not the image (bytes/base64) itself. | boolean | no | all | yes |
| faceDetectionMode | Face detection mode | string | no | all | no |
| faceDetectionLandmarks | Face detection coordinates | object | no | all | partially |
| faceDetectionClassifications | Facial examination type | string | no | all | no |
| onSubjectAreaChanged | This event is triggered when substantial changes are detected in the following objects | function | no | ios | no |
| onCameraReady | Camera ready callback | function | no | all | yes |
| onMountError | An incorrect callback occurred | function | no | all | yes |
| onStatusChange | Callbacks for camera state changes | function | no | all | yes |
| onAudioInterrupted | A callback when an audio session is interrupted or cannot be started for any reason | function | no | ios | no |
| onAudioConnected | Audio is connected to a callback | function | no | ios | yes |
| onPictureTaken | A callback when taking a photo | function | no | ios | yes |
| onRecordingStart | Start the callback for recording the video | function | no | ios | yes |
| onRecordingEnd | The callback to stop recording the video | function | no | ios | yes |
| onTap | Touch the camera preview view's callback | function | no | all | yes |
| onDoubleTap | Double-click the callback for the camera preview view | function | no | all | yes |
| onBarCodeRead | Scan successful callback | function | no | all | yes |
| onGoogleVisionBarcodesDetected | Callback when a Google visual barcode is detected | function | no | all | yes |
| onFaceDetectionError | Face detection error callback | function | no | all | yes |
| onFacesDetected | Face detection callback | function | no | all | yes |
| onTextRecognized | Check the callback when the text is reached | function | no | all | yes |
静态方法
| Name | Description | Type | Required | Platform | HarmonyOS Support | | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- | -------- | -------- | ----------------- | | detectFacesAsync | Detect faces in local images. | Promise<Face[]> | No | All | Yes | | takePictureAsync | Returns a promise with TakePictureResponse. | Promise | No | All | Yes | | recordAsync | Returns a promise with RecordResponse. | Promise | All | Yes | Yes | | refreshAuthorizationStatus | Allows to make RNCamera check Permissions again and set status accordingly. | Promise | All | Yes | Yes | | stopRecording | Should be called after recordAsync() to make the promise be fulfilled and get the video uri.. | Promise | All | Yes | Yes | | pausePreview | Pauses the preview. The preview can be resumed again by using resumePreview(). | Promise | All | Yes | Yes | | resumePreview | Resumes the preview after pausePreview() has been called. | Promise | All | Yes | Yes | | getSupportedRatiosAsync | Android only. Returns a promise. The promise will be fulfilled with an object with an array containing strings with all camera aspect ratios supported by the device. | Promise<string[]> | All | Yes | Yes | | checkIfVideoIsValid | Check that the video is valid | Promise | All | Yes | Yes | | getCameraIdsAsync | Returns a promise. The promise will be fulfilled with an array containing objects with all camera IDs and type supported by the device. | Promise<HardwareCamera[]> | All | Yes | Yes | | isRecording | iOS only. Returns a promise. The promise will be fulfilled with a boolean indicating if currently recording is started or stopped. | Promise | All | Yes | Yes |
遗留问题
- [ ] onSubjectAreaChanged 不支持:当检测到以下对象发生实质性更改时将触发此事件 issue#1
- [ ] keepAudioSession 不支持:保持音频会话 issue#2
- [ ] whiteBalance:不支持白平衡 issue#3
- [ ] permissionDialogTitle,不支持:配置安卓权限对话框标题 issue#4
- [ ] permissionDialogMessage,不支持:配置安卓权限对话框标题 issue#5
- [ ] androidRecordAudioPermissionOptions,不支持:配置安卓录音权限选项 issue#6
- [ ] androidCameraPermissionOptions,不支持:配置安卓相机权限选项 issue#7
- [ ] rectOfInterest,不支持:配置感兴趣的矩形区域属性 issue#8
- [ ] googleVisionBarcodeMode issue#9
- [ ] cameraViewDimensions,不支持:设置相机尺寸属性 issue#10
- [ ] googleVisionBarcodeMode,不支持:设置谷歌视觉条码模式 issue#11
- [ ] faceDetectionMode,不支持:设置人脸检测模式 issue#12
- [ ] faceDetectionClassifications,不支持:设置面部检查类型 issue#13
- [ ] recordAsync,不支持:异步录制视频设置optionissue#14
- [ ] faceDetectionLandmarks属性,部分支持缺少脸颊耳朵坐标点issue#15
- [ ] onGoogleVisionBarcodesDetected回调函数,兼容性支持,只返回onBarCodeRead部分属性issue#16
- [ ] googleVisionBarcodeType属性,兼容性支持barCodeTypes部分支持类型issue#17
其他
开源协议
本项目基于 The MIT License (MIT) ,请自由地享受和参与开源。
