HarmonyOS6 - 鸿蒙相机拍照和相册选图实战案例
开发环境为:
开发工具:DevEco Studio 6.0.1 Release
API版本是:API21
本文所有代码都已使用模拟器测试成功!
1. 效果
相机拍照和相册选图视频演示
2. 需求
需求很简单:
- 用户可以直接从图库中选择一张图片在页面中展示出来
- 用户可以选择拍照,然后将拍出来的照片在页面中显示出来
注意:本文实现以上需求的代码,不需要在module.json5文件中配置任何权限
3. 实战
1. 开发思路
- 模块导入:导入相机、相册访问、用户提示等鸿蒙原生能力模块
- 拍照功能:使用cameraPicker创建相机选择器,配置摄像头位置和媒体类型,返回照片URI
- 相册选择:使用photoAccessHelper创建相册选择器,配置选择图片类型和数量限制
- 异常处理:捕获操作异常,通过promptAction给用户友好提示
- 封装导出:将功能封装为工具类并导出实例,便于页面调用
2. 代码
页面代码如下:
js
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工具类代码如下:
js
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()
最后
- 希望本文对你有所帮助!
- 本人如有任何错误或不当之处,请留言指出,谢谢!