#HarmonyOS NEXT体验官#水印相机 原创
水印相机
项目背景描述
如今,图像和视频的记录与分享已经成为人们日常生活和工作中不可或缺的一部分。然而,对于许多用户来说,单纯的拍摄往往无法满足其特定的需求。
随着社交媒体的兴起和信息传播的快速发展,用户对于所拍摄内容的个性化、精准化以及专业性有了更高的要求。在这样的背景下,水印相机应运而生。
水印相机旨在为用户提供更加丰富和实用的功能。添加当前地理位置的功能,能够让用户在拍摄的瞬间准确记录下所在的位置信息,这对于旅行记录、工作现场汇报、活动举办地点的标注等场景具有重要意义。
添加水印的功能则赋予了照片和视频独特的标识,无论是个人版权声明、品牌宣传还是特定活动的标记,都能通过水印清晰展现。
同时,能够修改视频分辨率以及动图的功能,满足了用户在不同平台和设备上的展示需求。不同的社交媒体平台对于视频分辨率和格式可能有不同的要求,用户可以根据实际情况进行灵活调整,以确保所拍摄的内容能够在各种渠道上得到最佳的呈现效果。
功能列表
1.拍照
2.视频拍摄
3.闪光灯控制
4.动图
5.图像稳定
6.存储功能
7.连续变焦等。
工程目录
├──entry/src/main/ets/
│ ├──constants
│ │ └──CameraConstants.ets
│ ├──entryability
│ │ └──EntryAbility.ets
│ ├──pages
│ │ ├──Index.ets // 主页
│ │ └──MovingPhotoPage.ets //动态图片预览页
│ ├──utils
│ │ ├──CameraShooter.ets // 拍照
│ │ └──VideoRecorder.ets // 录像
└──entry/src/main/resource // 应用静态资源目录
实现思路
使用camera kit拍摄以及photoAccessHelper进行保存图片和视频。以及ArkUI的使用。
具体实现
- 页面背景添加水印,方法一:Stack层叠布局,使用Canvas绘制水印放在最上层。
- 页面背景添加水印,方法二:封装Canvas绘制水印组件为Builder,然后在需要添加的页面组件上添加overlay属性。
- 保存图片添加水印:获取图片数据,createPixelMap,使用OffScreenContext在指定位置绘制水印,最后保存带水印图片。
- 拍照图片添加水印:打开相机,获取存储fileUri,然后存入沙箱,获取图片数据,createPixelMap,绘制水印,最后保存带水印图片。
场景整体介绍
原理介绍
三方相机开放能力采用与系统相机统一底层接口调用方式,使最终的拍摄保持系统级效果。
整体流程
本场景解决方案按照如下流程实现三方相机效果,推荐开发者参考相同流程进行接入,以保证更好体验:
拍照
应用可以点击底部圆形按钮拍摄照片,同时可以调节变焦,闪光灯等参数。
关键代码片段
1、创建CameraManager对象,需要通过UIContext创建,用来对相机进行操作。
let cameraManager: camera.CameraManager = camera.getCameraManager(getContext());
2、获取相机列表,系统会提供前置和后置相机,供开发者选择切换。
let cameraArray: Array<camera.CameraDevice> = cameraManager.getSupportedCameras();
3、选择摄像头,创建输入流,作为预览流和拍照流的提供方。
cameraInput = cameraManager.createCameraInput(cameraArray[0])await cameraInput.open();
4、获取相机设备支持的输出流能力,此处指定NORMAL_PHOTO获取的是照片流,用来创建拍照输出流和预览输出流。
let cameraOutputCap: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(cameraArray[0], camera.SceneMode.NORMAL_PHOTO);
5、创建预览输出流,通过surfaceId绑定显示组件XComponent。
let previewProfilesArray: Array<camera.Profile> = cameraOutputCap.previewProfiles;
previewOutput = cameraManager.createPreviewOutput(previewProfilesArray[0], surfaceId);
6、创建拍照输出流,可以输出照片文件。
let photoProfilesArray: Array<camera.Profile> = cameraOutputCap.photoProfiles;
photoOutPut = cameraManager.createPhotoOutput(photoProfilesArray[0]);
7、创建相机会话,用于控制修改拍照参数。
photoSession = cameraManager.createSession(camera.SceneMode.NORMAL_PHOTO) as camera.PhotoSession;
8、开始配置会话,向会话中添加各路输入输出流,之后可以拍照。
photoSession.beginConfig();
photoSession.addInput(cameraInput);
photoSession.addOutput(previewOutput);
photoSession.addOutput(photoOutPut);
await photoSession.commitConfig();
await photoSession.start()
9、调节闪光灯,通过FLASH_MODE_AUTO设置为自动模式,目前支持关闭,自动,常亮,打开。
photoSession.setFlashMode(camera.FlashMode.FLASH_MODE_AUTO);
10、调节自动变焦模式,通过FOCUS_MODE_CONTINUOUS_AUTO设置为自动模式。目前支持连续自动对焦、自动对焦、手动对焦。
photoSession.setFocusMode(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO);
11、调节相机焦距,超出范围则只保留支持范围的值。
photoSession.setZoomRatio(zoom);
12、点击拍照,通过QUALITY_LEVEL_HIGH选择高质量模式。
let settings: camera.PhotoCaptureSetting = {
quality: camera.QualityLevel.QUALITY_LEVEL_HIGH,
rotation: camera.ImageRotation.ROTATION_0,
};
photoOutPut.capture(settings, () => {});
13、保存图片,此处需要调用系统图库接口photoAccessHelper。
let options: photoAccessHelper.CreateOptions = {
title: Date.now().toString()
};
let accessHelper: photoAccessHelper.PhotoAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
let photoUri: string = await accessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg', options);
// createAsset的调用需要ohos.permission.READ_IMAGEVIDEO和ohos.permission.WRITE_IMAGEVIDEO的权限
let file: fileIo.File = fileIo.openSync(photoUri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
await fileIo.write(file.fd, buffer);
fileIo.closeSync(file);
14、预览图片,此处需要调用文件预览组件,需要注意格式mimeType必须与文件类型相对应。
let options: photoAccessHelper.CreateOptions = {
title: Date.now().toString()
};
let accessHelper: photoAccessHelper.PhotoAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
let photoUri: string = await accessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg', options);
// createAsset的调用需要ohos.permission.READ_IMAGEVIDEO和ohos.permission.WRITE_IMAGEVIDEO的权限
let file: fileIo.File = fileIo.openSync(photoUri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
await fileIo.write(file.fd, buffer);
fileIo.closeSync(file);
完毕。