#DAYU200体验官# ArkUI相机开发踩坑之路 原创 精华
前言
非常有幸被选中成为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调用
时序图:
引用的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并不匹配(以上仅为个人猜测)。
感谢楼主分享避坑经验