Introducing Socket Firewall: Free, Proactive Protection for Your Software Supply Chain.Learn More
Socket
Book a DemoInstallSign in
Socket

@ohmi/react-native-camera

Package Overview
Dependencies
Maintainers
7
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ohmi/react-native-camera

A Camera component for React Native. Also reads barcodes.

latest
npmnpm
Version
4.2.1-1.4.2
Version published
Weekly downloads
2
100%
Maintainers
7
Weekly downloads
 
Created
Source

模板版本:v0.2.2

@ohmi/react-native-camera

Supported platforms License

[!TIP] Gitee 地址

介绍

本项目基于react-native-camera开发。

安装与使用

请到三方库的 Releases 发布地址查看配套的版本信息:@ohmi/react-native-camera Releases 。对于未发布到npm的旧版本,请参考安装指南安装tgz包。

进入到工程目录并输入以下命令:

npm

npm install @ohmi/react-native-camera

yarn

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,
  },
});

目前 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.etsentry/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 的效果。

NameDescriptionTypeRequiredPlatformHarmonyOS Support
zoomThis property specifies the zoom value of the camera. Ranges from 0 to 1. Default to 0numbernoAllyes
maxZoomThe maximum zoom value of the camera. Defaults to 0.numbernoAllyes
typeThis property defines which camera on the phone the component is using. Possible values:'front'/'back'noAllyes
focusModeCamera focus mode. Default: on'on'/'off'noAllyes
zoomModeEnable the pinch to zoom gesture. Default: on'on'/'off'noAllyes
zoomControl the zoom. Default: 1.0numbernoAllyes
maxZoomMaximum zoom allowed (but not beyond what camera allows). Default: undefined (camera default max)numbernoAllyes
cameraIdFor selecting from multiple cameras on Android devices. See 2492 for more info. Can be retrieved withstringnoAllyes
flashModeDetermines the state of the camera flash. Has the following possible statesstringnoAllyes
ratioA string representing the camera ratio in the format 'height:width'. Default is "4:3".stringnoAllyes
pictureSizeThis prop has a different behaviour for Android and iOS and should rarely be set.stringnoAllyes
autoFocusPointOfInterestSetting this property causes the auto focus feature of the camera to attempt to focus on the part of the image at this coordiate.objectnoallyes
captureAudioAndroid only. Enable or disable the shutter sound when capturing a photo. Default: trueBooleannoAndroidyes
ratioOverlayShow a guiding overlay in the camera preview for the selected ratio. Does not crop image as of v9.0. Example: '16:9'StringnoiOSyes
ratioOverlayColorAny color with alpha. Default: '#ffffff77'StringnoAllyes
resetFocusTimeoutDismiss tap to focus after this many milliseconds. Default 0 (disabled). Example: 5000 is 5 seconds.NumbernoAllyes
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.BooleannoiOSno
focusDepthManually 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.numbernoallno
whiteBalanceA camera’s white balance setting allows you to control the color temperature in your photos by cooling down or warming up the colors.stringnoallyes
exposureValue: float from 0 to 1.0, or -1 (default) for auto.stringnoallyes
useNativeZoomBoolean to turn on native pinch to zoom. Works with the maxZoom property on iOS.BooleannoiOSyes
permissionDialogTitleAndroid Permissions dialog titlestingnoandroidno
permissionDialogMessageAndroid Permissions dialog messagestringnoandroidno
androidRecordAudioPermissionOptionsAndroid recording permission optionsstingnoandroidno
androidCameraPermissionOptionsAndroid camera permission optionsstingnoandroidno
notAuthorizedViewBy 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.elementnoallyes
pendingAuthorizationViewBy 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.elementnoallyes
rectOfInterestAn {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.objectnoallno
cameraViewDimensionsAn {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 Androidobjectnoandroidno
playSoundOnCaptureBoolean to turn on or off the camera's shutter sound (default false). Note that in some countries, the shutter sound cannot be turned off.booleannoallyes
playSoundOnRecordBoolean to turn on or off the camera's record sound (default false)booleannoallyes
videoStabilizationModeThe video stabilization mode used for a video recording.stringnoallno
defaultVideoQualityThis option specifies the quality of the video to be taken. The possible values are:2160p,1080p,720p,480p,4:3,288pstringnoallyes
barCodeTypesAn array of barcode types to search for. Defaults to all types listed above. No effect if onBarCodeRead is undefined.stringnoallyes
googleVisionBarcodeTypeLike barCodeTypes, but applies to the Firebase MLKit barcode detector.stringnoallpartially
googleVisionBarcodeModeGoogle Visual bar code patternstringnoallno
detectedImageInEventWhen detectedImageInEvent is false (default), onBarCodeRead / onBarcodesDetected only gives metadata, but not the image (bytes/base64) itself.booleannoallyes
faceDetectionModeFace detection modestringnoallno
faceDetectionLandmarksFace detection coordinatesobjectnoallpartially
faceDetectionClassificationsFacial examination typestringnoallno
onSubjectAreaChangedThis event is triggered when substantial changes are detected in the following objectsfunctionnoiosno
onCameraReadyCamera ready callbackfunctionnoallyes
onMountErrorAn incorrect callback occurredfunctionnoallyes
onStatusChangeCallbacks for camera state changesfunctionnoallyes
onAudioInterruptedA callback when an audio session is interrupted or cannot be started for any reasonfunctionnoiosno
onAudioConnectedAudio is connected to a callbackfunctionnoiosyes
onPictureTakenA callback when taking a photofunctionnoiosyes
onRecordingStartStart the callback for recording the videofunctionnoiosyes
onRecordingEndThe callback to stop recording the videofunctionnoiosyes
onTapTouch the camera preview view's callbackfunctionnoallyes
onDoubleTapDouble-click the callback for the camera preview viewfunctionnoallyes
onBarCodeReadScan successful callbackfunctionnoallyes
onGoogleVisionBarcodesDetectedCallback when a Google visual barcode is detectedfunctionnoallyes
onFaceDetectionErrorFace detection error callbackfunctionnoallyes
onFacesDetectedFace detection callbackfunctionnoallyes
onTextRecognizedCheck the callback when the text is reachedfunctionnoallyes

静态方法

NameDescriptionTypeRequiredPlatformHarmonyOS Support
detectFacesAsyncDetect faces in local images.Promise<Face[]>NoAllYes
takePictureAsyncReturns a promise with TakePictureResponse.PromiseNoAllYes
recordAsyncReturns a promise with RecordResponse.PromiseAllYesYes
refreshAuthorizationStatusAllows to make RNCamera check Permissions again and set status accordingly.PromiseAllYesYes
stopRecordingShould be called after recordAsync() to make the promise be fulfilled and get the video uri..PromiseAllYesYes
pausePreviewPauses the preview. The preview can be resumed again by using resumePreview().PromiseAllYesYes
resumePreviewResumes the preview after pausePreview() has been called.PromiseAllYesYes
getSupportedRatiosAsyncAndroid 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[]>AllYesYes
checkIfVideoIsValidCheck that the video is validPromiseAllYesYes
getCameraIdsAsyncReturns a promise. The promise will be fulfilled with an array containing objects with all camera IDs and type supported by the device.Promise<HardwareCamera[]>AllYesYes
isRecordingiOS only. Returns a promise. The promise will be fulfilled with a boolean indicating if currently recording is started or stopped.PromiseAllYesYes

遗留问题

  • 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) ,请自由地享受和参与开源。

Keywords

barcode

FAQs

Package last updated on 18 Aug 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts