实现自定义相机拍照鸿蒙示例代码

鸿蒙场景化示例代码技术工程师
发布于 2025-2-28 16:54
3.0w浏览
0收藏

本文原创发布在华为开发者社区

介绍

本示例实现了自定义相机拍照功能以及保存图片功能,用到的API如下。

  • 使用@kit.CameraKit实现自定义相机拍照、双路预览功能
  • 使用@kit.MediaLibraryKit、@kit.ImageKit、@kit.CoreFileKit、安全保存控件SaveButton实现图片保存到系统图库
  • 使用@kit.MediaLibraryKit实现图库图片/视频选择
  • 使用@kit.CoreFileKit实现保存文件到文件管理器中

实现自定义相机拍照源码链接

效果预览

实现自定义相机拍照鸿蒙示例代码-鸿蒙开发者社区

使用说明

  • 打开应用,展示“拍照”、“图库”两个按钮。
  • 点击“拍照”按钮,即可进入拍照界面,注意当首次使用该功能时,需要用户进行授权,授权后才可使用。
  • 点击“图库”按钮,即可拉起系统相册,访问系统相册图片进行保存和读取。

实现思路

主页的设计

  1. 设置拍照按钮,点击后进行授权询问,requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗,用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限。授权后即可跳转自定义照相机页面。
.onClick(() => {
  let permissions: Array<Permissions> = [
    ···
  ];
  let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager();
  atManager.requestPermissionsFromUser(this.context, permissions).then((data: PermissionRequestResult) => {
    ···
  })
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  1. 设置图库按钮,点击后即可拉起系统相册,进行图片的保存和读取。
Button('图库')
  .width(200)
  .height(30)
  .onClick(() => {
    this.imagePicker();
  })
  .margin({ top: 30 })
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  1. 构造imagePicker()函数,拉起图片选择。
imagePicker() {
  try {
    let photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
    photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_VIDEO_TYPE;
    photoSelectOptions.maxSelectNumber = 1;
    let photoPicker = new photoAccessHelper.PhotoViewPicker();
    photoPicker.select(photoSelectOptions).then((photoSelectResult: photoAccessHelper.PhotoSelectResult) => {
      this.curFile = photoSelectResult.photoUris[0];
      if (this.curFile) {
        ···
      }
    })
  } 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  1. 构造isVideoType()函数,用以判断所要保存的文件是image类型还是video类型。如果typeId == uniformTypeDescriptor.UniformDataType.IMAGE.toString(),则返回false;如果typeId == uniformTypeDescriptor.UniformDataType.VIDEO.toString(),则返回true。
isVideoType(fileUri: string): boolean {
  try {
    let fileExtention = fileUri.substring(fileUri.lastIndexOf('.'));
    let typeId = uniformTypeDescriptor.getUniformDataTypeByFilenameExtension(fileExtention);
    ···
    let typeObj: uniformTypeDescriptor.TypeDescriptor = uniformTypeDescriptor.getTypeDescriptor(typeId);
    return typeObj.belongingToTypes.some((s) => s == uniformTypeDescriptor.UniformDataType.VIDEO.toString())
  } 
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

自定义相机的页面的实现

  1. 构建createCameraManager()函数,创建camera对象,监听相机状态变化
createCameraManager() {
  let cameraManager: camera.CameraManager = camera.getCameraManager(this.context);
  this.cameraManager = cameraManager;
  ···
  this.cameraManager.on();
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  1. 创建安全控件按钮,使用安全控件创建文件,选择通过文件管理写入文件
SaveButton(this.saveButtonOptions)
    .onClick(async (event, result: SaveButtonOnClickResult) => {
      ···
      ···
      ···
    })
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  1. 创建拍照按钮,通过拍照流实现:点击拍照,从imageReceiver中获取图片,实现拍照。
.onClick(async () => {
  let photoCaptureSetting: camera.PhotoCaptureSetting = {
    quality: camera.QualityLevel.QUALITY_LEVEL_HIGH,
    rotation: camera.ImageRotation.ROTATION_0 
  }
  await this.photoOutput?.capture(photoCaptureSetting).catch((error: BusinessError) => {
    console.error(`CameraDemo Failed to capture the photo ${error.message}`); 
  })
  this.hasPicture = true;
})
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  1. 获取支持指定的相机设备对象
  let cameraDevices: Array<camera.CameraDevice> = [];
  • 1.
  1. 创建相机输入流
try {
  this.cameraInput = this.cameraManager.createCameraInput(cameraDevices[0]);
}
  • 1.
  • 2.
  • 3.
  1. 打开相机,获取指定的相机设备对象支持的模式,获取相机设备支持的输出流能力,创建相机预览输出流,监听previewOutput错误信息,监听previewOutput2错误信息,创建拍照输出流,调用上面的回调函数来保存图片,创建相机会话,监听session错误信息,开始会话配置,向会话中添加相机输入流,向会话中添加预览输出流等依次操作。

分类
收藏
回复
举报


回复
    相关推荐