#DAYU200体验官# ArkUI相机开发踩坑之路 原创 精华

panda_coder
发布于 2022-5-26 18:59
浏览
3收藏

前言

非常有幸被选中成为DAYU200的体验官的一员(感谢一波金主),相比较Hi3516开发板,DAYU200的操作体验那可是质的飞越,终于不用忍受3516上点击或进行一个操作等待好几秒的延时。

效果演示

演示视频

踩坑之路

1.权限赋能

参照文档,在使用相机时,需要使用到ohos.permission.CAMERA的权限。
在config.json中申请相机权限

 "reqPermissions": [
      {
        "name": "ohos.permission.CAMERA"
      }
    ],

因为相机是敏感权限,同时需要在主页面的aboutToAppear()方法中调用主动授权接口

  aboutToAppear() {
    SysPermissionUtils.check("ohos.permission.CAMERA").then((isNeedPermission) => {
      if (isNeedPermission) {
        let permissions = [
          "ohos.permission.CAMERA"
        ]
        SysPermissionUtils.request(permissions, (isAuth) => {
          this.init()
        })
      } else {
        this.init();
      }
    })
  }

SysPermissionUtils文件

import bundle from '@ohos.bundle'
import abilityAccessCtrl from '@ohos.abilityAccessCtrl'
import featureAbility from '@ohos.ability.featureAbility';

const bundleName:string="" //Your App BundleName

export default class SysPermissionUtils {
  static async check(permission) {
    let bundleFlag = 0
    let userId = 100
    let appInfo = await bundle.getApplicationInfo(bundleName, bundleFlag, userId)
    let tokenId = appInfo.accessTokenId
    let atManager = abilityAccessCtrl.createAtManager()
    let result = await atManager.verifyAccessToken(tokenId, permission)
    return result == abilityAccessCtrl.GrantStatus.PERMISSION_DENIED
  }

  static request(targetPermissionArray, callback) {
    if (targetPermissionArray instanceof Array && targetPermissionArray.length > 0) {
      featureAbility.getContext().requestPermissionsFromUser(targetPermissionArray,666, (result) => {
        callback(result.code === 0)
      })
    }
  }
}

2.API调用

时序图:
#DAYU200体验官# ArkUI相机开发踩坑之路-鸿蒙开发者社区

引用的API:
@ohos.multimedia.camera
@ohos.multimedia.image
通过camera、image类初始化CameraManager、ImageReceiver、CaptureSession、PreviewOutput、PhotoOutput的实例,再通过CameraManager获取当前设备所有相机,并通过选取的相机Id初始化CameraInput。
CaptureSession实例注入PreviewOutPut、PhotoOutput并提交配置
预览功能:
开启预览:调用captureSession的start()方法
关闭预览:调用captureSession的stop()方法
拍照功能:
调用photoOutPut的capture()方法,调用方法后图片数据通过ImageReceiver的on(“imageArrival”,callback)回调方法返回

3.XComponent组件

XComponent是API8新增的组件,其作用是用于EGL/OpenGLES和媒体数据写入,并显示在XComponent组件。
目前Xcomponent只能用于媒体数据写入
为什么单独拿出XComponent组件来讲,因为我在最初开发时还API9的文档还没出来,靠着SDK的注释(如下)不断尝试,但仅靠注释根本不知道此处surfaceId究竟是何方神圣,终于在API9的相机文档出来后,终于解开了疑惑,但也对他印象深刻。

  /**
   * Creates a PreviewOutput instance.
   * @param surfaceId Surface object id used in camera preview output.
   * @param callback Callback used to return the PreviewOutput instance.
   * @since 9
   * @syscap SystemCapability.Multimedia.Camera.Core
   */
  function createPreviewOutput(surfaceId: string, callback: AsyncCallback<PreviewOutput>): void;

4.避坑

如果你只加载预览界面,也不要偷懒,把PhotoOutput也注入进CaptureSession,否则也会遇到折腾我几天的坑,预览界面的绘画窗体与XComponent窗体不符合,且XComponent窗体背景可以透视到桌面界面。
个人猜测原因是PhotoOutput在初始化时传入了ImageReceiverId,而ImageReceiver在实例化时传入了图片的size,如果在CaptureSession中不注入PhotoOutput,则使用默认的size,默认的size与XComponent的size并不匹配(以上仅为个人猜测)。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
相机开发时序图.zip 154.04K 62次下载
已于2022-5-26 18:59:24修改
4
收藏 3
回复
举报
1条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

感谢楼主分享避坑经验

回复
2022-5-27 10:20:57
回复
    相关推荐