基于OpenHarmony 4.1Release的分布式相机分布式图库实现
一、环境配置 平台硬件: RK3568OS版本:OpenHarmony 4.1 Release32bit(4.1.7.8)sdk:API11(full sdk)DevEco:4.1.0.400二、项目介绍 本项目实现了分布式认证,分布式相机预览拍照,分布式图库
·
一、环境配置
- 平台硬件: RK3568
- OS版本:OpenHarmony 4.1 Release 32bit(4.1.7.8)
- sdk:API11(full sdk)
- DevEco:4.1.0.400
二、项目介绍
本项目实现了分布式认证,分布式相机预览拍照,分布式图库同步显示删除
三、项目实现注意事项
3.1分布式图库需要基于分布式文件系统实现,分布式文件系统需要预先登录分布式账号
参考 @ohos.account.distributedAccount (分布式帐号管理) (openharmony.cn)
/**
* 分布式账号类
* 功能:
* 1.判断是否登录
* 2.登录默认账号
*/
export class DistributedAccountHelper {
private distributedAccountAbility: account_distributedAccount.DistributedAccountAbility;
constructor() {
this.distributedAccountAbility = account_distributedAccount.getDistributedAccountAbility();
}
/**
* 检查当前登录分布式账号信息
* @returns Promise<boolean>
*/
checkLogin(): Promise<void> {
return new Promise((resolve, reject) => {
this.distributedAccountAbility.getOsAccountDistributedInfo().then((data: account_distributedAccount.DistributedInfo) => {
Logger.info(TAG, 'distributed information: ' + JSON.stringify(data));
resolve();
}).catch((err: BusinessError) => {
Logger.info(TAG, 'getOsAccountDistributedInfo exception: ' + JSON.stringify(err));
resolve();
});
});
}
/**
* 登录分布式账号
* @returns Promise<void>
*/
login(): Promise<void> {
let distributedInfo: account_distributedAccount.DistributedInfo = {
name: 'ZhangSan',
id: '12345',
event: 'Ohos.account.event.LOGIN',
};
return new Promise((resolve, reject) => {
this.distributedAccountAbility.setOsAccountDistributedInfo(distributedInfo).then(() => {
Logger.info(TAG, 'setOsAccountDistributedInfo LOGIN successfully');
resolve();
}).catch((err: BusinessError) => {
Logger.info(TAG, 'setOsAccountDistributedInfo exception: ' + JSON.stringify(err));
reject(err);
});
});
}
}
页面出现前进行账号登录。
async aboutToAppear() {
// 登陆分布式账号
await this.dealDistributedAccount();
// 初始化分布式model
RemoteDeviceModel.createRemoteDeviceModel();
Logger.info(TAG, 'DeviceMangerPage init success!');
}
async dealDistributedAccount() {
const helper = new DistributedAccountHelper();
// 登陆自己的分布式账号
await helper.login();
// 检查结果
await helper.checkLogin();
}
3.2分布式文件系统不同设备间同步涉及数据安全,如果本设备安全等级低于文件安全等级,则不能同步。
参考@ohos.file.securityLabel (数据标签) (openharmony.cn)
对于rk3568,本身没有安全芯片,安全等级最低,为S1,而分布式文件夹中的文件默认安全等级为S3,所以普通情况下已经登录同一分布式账号的应用,只能看到分布式文件夹有文件,有文件名,但是访问会出现Permission denied,参数错误等。
解决办法:手动降低文件数据安全等级,以下为适用于rk3568的代码示例。
注意,代码实现中的s0-s4对应实际安全等级S1-S5
//设置文件的数据等级为s0
securityLabel.setSecurityLabel(localPhotoUri, 's0').then(() => {
Logger.info(TAG, `Succeeded in setSecurityLabeling. ${localPhotoUri}`);
}).catch((err: BusinessError) => {
Logger.error(TAG, `Failed to setSecurityLabel. Code: ${err.code}, message: ${err.message}`);
});
3.3 分布式相机使用远端设备进行拍照时(参考最佳实践进行实现),无法进入'photoAvailable'回调,无法获取原始camera.Photo。(不清楚是否为个例,欢迎讨论)
参考@ohos.multimedia.image (图片处理) (openharmony.cn)
解决办法:分布式相机只能预览,不能拍照,那就从预览流取出数据,保存为图片(其实这中方法也适用于本地设备拍照,但是最佳实践是一个输出流一个预览流)。
普通拍照方法:
/**
* 拍照回调注册类
* @param photoOutput
*/
async setPhotoOutputCb(photoOutput: camera.PhotoOutput) {
//设置回调之后,调用photoOutput的capture方法,就会将拍照的buffer回传到回调中
//分布式拍照无法进入该回调,新增distributedTakePicture
photoOutput.on('photoAvailable', (errCode: BusinessError, photo: camera.Photo): void => {
Logger.info(TAG, 'getPhoto start');
Logger.info(TAG, `err: ${JSON.stringify(errCode)}`);
if (errCode || photo === undefined) {
Logger.error(TAG, 'getPhoto failed');
return;
}
let imageObj: image.Image = photo.main;
imageObj.getComponent(image.ComponentType.JPEG, (errCode: BusinessError, component: image.Component): Promise<void> => {
Logger.info(TAG, 'getComponent start');
if (errCode || component === undefined) {
Logger.error(TAG, 'getComponent failed');
return;
}
let buffer: ArrayBuffer;
if (component.byteBuffer) {
buffer = component.byteBuffer;
} else {
Logger.error(TAG, 'byteBuffer is null');
return;
}
this.saveImage(buffer, imageObj);
});
});
photoOutput.on('error', (err: BusinessError): void => {
Logger.error(TAG, `${JSON.stringify(err)}`);
});
}
分布式设备拍照方法:
distributedTakePicture(surfaceId: string) {
//rk createPreviewOutput 只支持{"format":3,"size":{"width":640,"height":480}}
let region: image.Region = { x: 0, y: 0, size: { width: 640, height: 480 } };
image.createPixelMapFromSurface(surfaceId, region).then(async (pixelMap: image.PixelMap) => {
Logger.info(TAG, 'Succeeded in creating pixelMap from Surface');
let packOpts: image.PackingOption = { format: "image/jpeg", quality: 100 }
const imagePackerApi: image.ImagePacker = image.createImagePacker();
await pixelMap.rotate(-90.0);
imagePackerApi.packing(pixelMap, packOpts, (err: BusinessError, data: ArrayBuffer) => {
if (err) {
Logger.error('Failed in packing the image.' + JSON.stringify(err))
} else {
this.saveImage(data);
Logger.info(TAG, 'Succeeded in packing the image.');
pixelMap.release();
}
})
}).catch((error: BusinessError) => {
Logger.error(TAG, 'Failed to create pixelMap ' + JSON.stringify(error));
});
}
四、项目源码
// 项目源码还在优化,关键问题上面已经解决,后续考虑捐献到社区,欢迎持续关注。
更多推荐
已为社区贡献5条内容
所有评论(0)