npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

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

Link

目前 HarmonyOS 暂不支持 AutoLink,所以 Link 步骤需要手动配置。

首先需要使用 DevEco Studio 打开项目里的 HarmonyOS 工程 harmony

1.在工程根目录的 oh-package.json 添加 overrides字段

{
  ...
  "overrides": {
    "@rnoh/react-native-openharmony" : "./react_native_openharmony"
  }
}

2.引入原生端代码

目前有两种方法:

  1. 通过 har 包引入(在 IDE 完善相关功能后该方法会被遗弃,目前首选此方法);
  2. 直接链接源码。

方法一:通过 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 的效果。

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