UvcCamera

简介

鸿蒙外接uvc摄像头预览操作程序

  1. 支持无界面/有界面预览
  2. 支持设置分辨率/曝光度等参数
  3. 使用设备为OpenHarmony

软件架构

当前为dev版本

安装教程

  1. ohpm i uvc_camera

使用说明

操作基础类 CameraManager

library_name

常量,需要预览画面时,给XComponentlibraryname参数设置 例:

 XComponent({
  id: "surface_uvc",
  type: XComponentType.SURFACE,
  libraryname: CameraManager.library_name,
  controller: this.xComponent
})
  .alignRules({
    left: { anchor: "__container__", align: HorizontalAlign.Start },
    right: { anchor: "__container__", align: HorizontalAlign.End },
    top: { anchor: "__container__", align: VerticalAlign.Top },
    bottom: { anchor: "__container__", align: VerticalAlign.Bottom }
  })
  .onLoad(async () => {
  })
  .backgroundColor("#fff")
debuggable

debug模式开关,打开后会有基础日志输出

let result = CameraManager.debuggable(true);
getUvcDevices

获取当前设备上的usb摄像头列表

let usbDevices = CameraManager.getUvcDevices();
getDeviceForId

根据传入的vId和pId获取对应的usb设备

let usbDevice = CameraManager.getDeviceForId(vId, pId);
checkDeviceUvc

检查当前设备是否是uvc摄像头设备

let isUvc = CameraManager.checkDeviceUvc(usbDevice);

打开摄像头

异步打开摄像头,需要Camera权限,且,需要申请usb临时权限,最大等待超时时间为10s

/**
 * usb类型打开
 */
function openUsbDevice() {
  try {
    let cameraDevice :CameraDevice = await CameraManager.openUsb(usbDevice);
    //打开成功,返回操作对象
  } catch (e) {
    //打开失败,返回异常信息
  }
}

/**
 * video类型打开
 */
function openUsbDevice() {
  try {
    let cameraDevice :CameraDevice = await CameraManager.openVideoCamera("/dev/video9");
    //打开成功,返回操作对象
  } catch (e) {
    //打开失败,返回异常信息
  }
}

关闭摄像头

//使用CameraDevice对象来进行后续操作
cameraDevice.close();

设置预览控件

设置当前usb设备数据绘制到对应的XComponent控件上,值为XComponent的id字段,

cameraDevice.setDisplaySurfaceId("surface_uvc")

设置使用分辨率

设置预览分辨率 支持格式YUY2/MJPEG 分辨率支持列表通过getSupportParameters获取

let result:boolean = cameraDevice.setPreviewSize(640, 480, CameraFormatMode.YUY2);

设置预览监听

cameraDevice.setPreviewListener((data:Uint8Array, width:number, height:number) => {

}, CameraResultFormat.RGBA);

开启预览

开启预览,建议在promise内使用

cameraDevice.startPreview();

关闭预览

关闭预览操作,使用CameraDevice对象

cameraDevice.stopPreview();

设置参数值

支持设置自动曝光/曝光度/分辨率/预览图形变换规则等参数

cameraDevice.setParameter(CameraParameter.AUTO_EXPOSURE, true);

获取参数信息

获取当前设置的参数信息

let autoExposure = cameraDevice.getParameter(CameraParameter.AUTO_EXPOSURE);

获取参数范围

可获取分辨率列表,支持的曝光度范围,亮度范围,等

let autoExposure = cameraDevice.getSupportParameters(CameraParameter.PREVIEW_SIZE);

设置usb断开监听

在usb设备被拔出后回调该监听

cameraDevice.setDetachedCloseListener(() => {

});

枚举/类

内置枚举/类说明

CameraDataFormat

预览监听返回的数据类型。 目前只支持 BGRRGBANV21

CameraPreviewFormat

预览分辨率使用的格式类型,根据分辨率列表返回值确定 目前支持MJPEGYUY2

IntRange

使用getSupportParameters时,当前返回值为范围值时使用,返回最大值和最小值 min:最小值 max:最大值

DisplayTransformState

对应当前surface窗口变化支持的类型

  • TRANSFORM_IDENTITY:无变化
  • TRANSFORM_MIRROR_HORIZONTAL:水平镜像
  • TRANSFORM_MIRROR_VERTICAL:垂直镜像
  • TRANSFORM_ROTATE_90:旋转90度
  • TRANSFORM_ROTATE_180:旋转180度
  • TRANSFORM_ROTATE_270:旋转270度
  • TRANSFORM_FLIP_H_ROTATE_90:旋转90度+水平镜像
  • TRANSFORM_FLIP_H_ROTATE_180:旋转180度+水平镜像
  • TRANSFORM_FLIP_H_ROTATE_270:旋转270度+水平镜像
  • TRANSFORM_FLIP_V_ROTATE_90:旋转90度+垂直镜像
  • TRANSFORM_FLIP_V_ROTATE_180:旋转180度+垂直镜像
  • TRANSFORM_FLIP_V_ROTATE_270:旋转270度+垂直镜像s

CameraParameter

目前支持设置/获取的参数信息

  • AUTO_EXPOSURE: 自动曝光状态
  • EXPOSURE: 曝光度值
  • BRIGHTNESS: 亮度值
  • CONTRAST: 对比度值
  • GAIN: 增益值
  • SATURATION: 饱和度
  • ZOOM: 缩放大小
  • DISPLAY_TRANSFORM: 窗口变化支持的类型,见DisplayTransformState
  • PREVIEW_SIZE: 分辨率信息
  • FOCUS:焦距
  • AUTO_FOCUS:自动聚焦
  • IRIS:光圈
  • AUTO_HUE:自动设置色值
  • HUE:色值
  • AUTO_WHITE_BALANCE:自动化白平衡
  • WHITE_BALANCE:白平衡
  • SCENE_MODE:场景模式
  • PRIVACY:隐私模式

CameraSupportParameters

获取支持的参数范围

  • AUTO_EXPOSURE:是否支持自动曝光
  • EXPOSURE:曝光度范围,为null或者 最大值 = 最小值时,表示不支持
  • BRIGHTNESS:亮度范围,为null或者 最大值 = 最小值时,表示不支持
  • CONTRAST:对比度范围,为null或者 最大值 = 最小值时,表示不支持
  • GAIN:增益值范围,为null或者 最大值 = 最小值时,表示不支持
  • SATURATION:饱和度范围,为null或者 最大值 = 最小值时,表示不支持
  • ZOOM:缩放范围,为null或者 最大值 = 最小值时,表示不支持
  • PREVIEW_SIZE:支持的分辨率列表
  • FOCUS:焦距范围,为null或者 最大值 = 最小值时,表示不支持
  • AUTO_FOCUS:是否支持自动聚焦
  • IRIS:光圈范围,为null或者 最大值 = 最小值时,表示不支持
  • AUTO_HUE:是否支持自动设置色值
  • HUE:色值范围,为null或者 最大值 = 最小值时,表示不支持
  • AUTO_WHITE_BALANCE:是否支持自动化白平衡
  • WHITE_BALANCE:白平衡范围,为null或者 最大值 = 最小值时,表示不支持
  • SCENE_MODE:场景模式范围,为null或者 最大值 = 最小值时,表示不支持
  • PRIVACY:是否支持隐私模式

CameraSize

分辨率信息

  • width: 宽度
  • height:高度
  • format:对应的分辨率,详见CameraPreviewFormat

例:


@Component
struct SurfaceChild {
private mCameraDevice : CameraDevice | null | undefined;
build() {
  NavDestination() {
    RelativeContainer() {
      XComponent({
        id: "surface_uvc",
        type: XComponentType.SURFACE,
        libraryname: CameraManager.library_name,
      })
        .alignRules({
          left: { anchor: "__container__", align: HorizontalAlign.Start },
          right: { anchor: "__container__", align: HorizontalAlign.End },
          top: { anchor: "__container__", align: VerticalAlign.Top },
          bottom: { anchor: "__container__", align: VerticalAlign.Bottom }
        })
        .onLoad(async () => {
        })
        .backgroundColor("#fff")
    }
    .width("100%")
    .height("100%")
  }
  .width("100%")
  .height("100%")
  .hideTitleBar(true)
  .onAppear(() => {
  })
  .onBackPressed(() => {
    return true;
  })
  .onShown(async () => {
    this.open();
  })
  .onHidden(() => {
    this.close();
  })
}


private updateRotation() {
  if (!this.mCameraDevice) {
    return;
  }
  this.mCameraDevice.setParameter(CameraParameter.DISPLAY_TRANSFORM, DisplayTransformState.TRANSFORM_ROTATE_90)
}

private async open() {
  hilog.debug(0x0000, "surfaceDraw", "获取到的设备信息:%{public}s", JSON.stringify(usbDevice));
  let devices = CameraManager.getUvcDevices();
  if (!devices || devices.length === 0) {
    return;
  }
  this.mCameraDevice = await CameraManager.openCamera(devices[0]);
  if (!this.mCameraDevice) {
    return;
  }
  this.initParameter();
  this.mCameraDevice.setDisplaySurfaceId("surface_uvc");
  this.mCameraDevice.setPreviewSize(640, 480, CameraFormatMode.YUY2);
  this.mCameraDevice.setPreviewListener((bytes, width, height) => {
    // hilog.warn(0x0000, "surfaceDraw", "当前数据帧:%{public}d,%{public}d*%{public}d", bytes.byteLength, width, height);
  }, CameraResultFormat.NV21)
  this.mCameraDevice.startPreview();
}

private initParameter() {
  if (!this.mCameraDevice) {
    return;
  }
  let currentSupportExposure = this.mCameraDevice.getSupportParameters(CameraSupportParameters.EXPOSURE);
  let currentSupportBrightness = this.mCameraDevice.getSupportParameters(CameraSupportParameters.BRIGHTNESS);
  let currentSupportContrast = this.mCameraDevice.getSupportParameters(CameraSupportParameters.CONTRAST);
  let currentSupportGain = this.mCameraDevice.getSupportParameters(CameraSupportParameters.GAIN);
  let currentSupportSaturation = this.mCameraDevice.getSupportParameters(CameraSupportParameters.SATURATION);
  let currentSupportPreviewSizes = this.mCameraDevice.getSupportParameters(CameraSupportParameters.PREVIEW_SIZE);
  let currentAutoExposure = this.mCameraDevice.getParameter(CameraParameter.AUTO_EXPOSURE) ?? false;
  let currentExposure = this.mCameraDevice.getParameter(CameraParameter.EXPOSURE);
  let currentBrightness = this.mCameraDevice.getParameter(CameraParameter.BRIGHTNESS);
  let currentGain = this.mCameraDevice.getParameter(CameraParameter.GAIN);
  let currentContrast = this.mCameraDevice.getParameter(CameraParameter.CONTRAST);
  let currentSaturation = this.mCameraDevice.getParameter(CameraParameter.SATURATION);
  let currentSelectPreviewSize = this.mCameraDevice.getParameter(CameraParameter.PREVIEW_SIZE)


  hilog.debug(0x0000, "UvcCamera", "分辨率列表:%{public}s", JSON.stringify(currentSupportPreviewSizes));
  hilog.debug(0x0000, "UvcCamera", "曝光度列表:%{public}s", JSON.stringify(currentSupportExposure));
  hilog.debug(0x0000, "UvcCamera", "亮度列表:%{public}s", JSON.stringify(currentSupportBrightness));
  hilog.debug(0x0000, "UvcCamera", "增益值列表:%{public}s", JSON.stringify(currentSupportGain));
  hilog.debug(0x0000, "UvcCamera", "对比度列表:%{public}s", JSON.stringify(currentSupportContrast));
  hilog.debug(0x0000, "UvcCamera", "饱和度列表:%{public}s", JSON.stringify(currentSupportSaturation));
  hilog.debug(0x0000, "UvcCamera", "当前自动曝光状态:%{public}s", JSON.stringify(currentAutoExposure));
  hilog.debug(0x0000, "UvcCamera", "当前曝光度:%{public}s", JSON.stringify(currentExposure));
  hilog.debug(0x0000, "UvcCamera", "当前亮度:%{public}s", JSON.stringify(currentBrightness));
  hilog.debug(0x0000, "UvcCamera", "当前增益值:%{public}s", JSON.stringify(currentSupportGain));
  hilog.debug(0x0000, "UvcCamera", "当前对比度:%{public}s", JSON.stringify(currentContrast));
  hilog.debug(0x0000, "UvcCamera", "当前饱和度:%{public}s", JSON.stringify(currentSaturation));
}

private close() {
  if (this.mCameraDevice) {
    this.mCameraDevice.stopPreview();
    this.mCameraDevice.close();
  }
}
}
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐