HarmonyOS6 - 鸿蒙相机拍照和相册选图实战案例

开发环境为:

开发工具:DevEco Studio 6.0.1 Release
API版本是:API21

本文所有代码都已使用模拟器测试成功!

1. 效果

相机拍照和相册选图视频演示

2. 需求

需求很简单:

  1. 用户可以直接从图库中选择一张图片在页面中展示出来
  2. 用户可以选择拍照,然后将拍出来的照片在页面中显示出来

注意:本文实现以上需求的代码,不需要在module.json5文件中配置任何权限

3. 实战

1. 开发思路

  1. 模块导入:导入相机、相册访问、用户提示等鸿蒙原生能力模块
  2. 拍照功能:使用cameraPicker创建相机选择器,配置摄像头位置和媒体类型,返回照片URI
  3. 相册选择:使用photoAccessHelper创建相册选择器,配置选择图片类型和数量限制
  4. 异常处理:捕获操作异常,通过promptAction给用户友好提示
  5. 封装导出:将功能封装为工具类并导出实例,便于页面调用

2. 代码

页面代码如下:

import { photoPicker } from '../common/utils/PhotoPicker';

const TAG = 'bobo'

/**
 * Desc: 案例:拍照+图库选图
 * Author: 波波老师(weixin: javabobo0513)
 */
@Entry
@Component
struct Page07 {
  //拍照得到的图片
  @State img: string = '';

  build() {
    Column({ space: 20 }) {

      Text('图片预览:')
        .fontSize(20)
        .fontWeight(600)

      Image(this.img)
        .width('100%')
        .height('50%')
        .objectFit(ImageFit.Contain)

      Row() {
        Button('相册')
          .onClick(() => {
            photoPicker.pickPhoto().then((res: string | void) => {
              this.img = res as string;
              console.log(TAG, '相册-this.img=' + this.img)
            })
          })
        Button('拍照')
          .onClick(() => {
            photoPicker.takePhoto().then((res: string) => {
              this.img = res;
              console.log(TAG, '拍照-this.img=' + this.img)
            })
          })
      }
      .justifyContent(FlexAlign.SpaceAround)
      .width('100%')

    }
    .padding(15)
    .width('100%')
    .height('100%')
    .alignItems(HorizontalAlign.Start)
  }
}

PhotoPicker工具类代码如下:

import { camera, cameraPicker } from '@kit.CameraKit';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { promptAction } from '@kit.ArkUI';

const TAG = 'bobo'

/**
 * 获取图片在页面中显示的工具类
 *    获取图片方式:
 *           1:图库选择
 *           2:拍照
 */
class PhotoPicker {
  //拍照
  async takePhoto(): Promise<string> {
    try {
      let pickerProfile: cameraPicker.PickerProfile = {
        //相机位置
        cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK, //后置相机
        videoDuration: 0, //录制的最大时长(单位:秒)。默认为0,不设置最大录制时长。
      };
      /**
       * PickerResult:相机选择器的处理结果
       *    resultCode:处理的结果,成功返回0,失败返回-1。
       *    resultUri:此处的resultUri为公共媒体路径
       *    mediaType:返回的媒体类型
       */
      let pickerResult: cameraPicker.PickerResult = await cameraPicker.pick(getContext(),
        [cameraPicker.PickerMediaType.PHOTO, cameraPicker.PickerMediaType.VIDEO], pickerProfile);
      //打印结果:照片={"resultCode":0,"resultUri":"file://media/Photo/7/IMG_1768657353_004/IMG_20260117_214053.jpg","mediaType":"photo"}
      console.log(TAG, '照片=' + JSON.stringify(pickerResult))
      if (pickerResult.mediaType === "photo" && pickerResult.resultUri != '') {
        return pickerResult.resultUri;
      }
    } catch (error) {
      console.log(TAG, '相机打开异常')
      promptAction.showToast({
        message: '相机打开异常!',
        duration: 5000
      })
    }
    return '';
  }

  //从相册中选图(photoAccessHelper版)
  async pickPhoto(): Promise<string | void> {
    const photoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
    photoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
    //选择图片数量
    photoSelectOptions.maxSelectNumber = 1;
    let photoPicker = new photoAccessHelper.PhotoViewPicker();
    try {
      const res = await photoPicker.select(photoSelectOptions)
      console.log(TAG, '从相册中选图片,res=', JSON.stringify(res))
      if (res.photoUris.length <= 0) {
        return
      }
      return res.photoUris[0];
    } catch (e) {
      console.log(TAG, '从相册中选图片error=', JSON.stringify(e))
    }
  }
}
//导出
export const photoPicker = new PhotoPicker()

最后

  • 希望本文对你有所帮助!
  • 本人如有任何错误或不当之处,请留言指出,谢谢!
Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐