文章的目的为了记录使用Arkts 进行Harmony app 开发学习的经历。本职为嵌入式软件开发,公司安排开发app,临时学习,完成app的开发。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。
相关链接:
开源 Arkts 鸿蒙应用 开发(一)工程文件分析-CSDN博客
开源 Arkts 鸿蒙应用 开发(二)封装库.har制作和应用-CSDN博客
开源 Arkts 鸿蒙应用 开发(三)Arkts的介绍-CSDN博客
开源 Arkts 鸿蒙应用 开发(四)布局和常用控件-CSDN博客
开源 Arkts 鸿蒙应用 开发(五)控件组成和复杂控件-CSDN博客
开源 Arkts 鸿蒙应用 开发(六)数据持久--文件和首选项存储-CSDN博客
开源 Arkts 鸿蒙应用 开发(七)数据持久--sqlite关系数据库-CSDN博客
android 链接(十三章):
开源 java android app 开发(一)开发环境的搭建_csdn 开源 java android app-CSDN博客
.net mvc链接(八章):
开源C# .net mvc 开发(一)WEB搭建_c#部署web程序-CSDN博客
本章内容主要是鸿蒙的多媒体使用,主要功能包括从相册选择图片、拍摄照片以及将图片保存到应用沙箱目录。
1.使用流程
2.相册和相机的使用
3.保存到沙箱
4.所有代码
5.显示效果
一、使用流程图

二、相册和相机的使用
2.1 使用**PhotoViewPicker
**选择图片
Button("打开相册照片")
.width('100%')
.height(40)
.onClick(async () => {
try {
let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
PhotoSelectOptions.maxSelectNumber = 1;
let photoPicker = new photoAccessHelper.PhotoViewPicker();
photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult: photoAccessHelper.PhotoSelectResult) => {
this.imageUri = PhotoSelectResult.photoUris[0] ? PhotoSelectResult.photoUris[0] : this.imageUri;
hilog.info(0x0000, TAG, 'PhotoViewPicker.select succeed, uri: ' + JSON.stringify(PhotoSelectResult));
}).catch((err: BusinessError) => {
hilog.error(0x0000, TAG, `PhotoViewPicker.select failed, error: ${err.code}, ${err.message}`);
});
} catch (error) {
let err: BusinessError = error as BusinessError;
hilog.error(0x0000, TAG, `PhotoViewPicker failed, error: ${err.code}, ${err.message}`);
}
this.isShowGet = false;
})
2.2 用cameraPicker调用设备相机
Button("相机拍摄照片")
.width('100%')
.height(40)
.onClick(async () => {
// [Start pick_file]
try {
let pickerProfile: cameraPicker.PickerProfile =
{ cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK };
//Select the action of pulling up the camera to take pictures.
let pickerResult: cameraPicker.PickerResult = await cameraPicker.pick(this.getUIContext().getHostContext(),
[cameraPicker.PickerMediaType.PHOTO], pickerProfile);
//Return the photo uri to the application.
this.imageUri = pickerResult.resultUri ? pickerResult.resultUri : this.imageUri;
hilog.info(0x0000, TAG, 'cameraPicker.pick succeed, uri: ' + JSON.stringify(pickerResult));
} catch (error) {
let err = error as BusinessError;
hilog.error(0x0000, TAG, `cameraPicker.pick failed, error: ${err.code}, ${err.message}`);
}
// [End pick_file]
this.isShowGet = false;
})
三、保存到沙箱,特别的是大量使用**async/await
**处理异步操作
async saveImageToSandbox() {
// 1. 检查图片URI
if (!this.imageUri) {
this.getUIContext().getPromptAction().showToast({
message: $r('app.string.no_image_alert'),
duration: 2000
});
return;
}
try {
// 2. 等待图片复制到沙箱
await copyImg2Sandbox(this.imageUri, this.path);
// 3. 创建ImageSource
this.imageSource = image.createImageSource(this.path);
// 4. 并行获取图片信息
await Promise.all([
new Promise<void>((resolve, reject) => {
this.imageSource!.getImageInfo((error, info) => {
error ? reject(error) : resolve();
});
}),
this.imageSource.getImageProperties([
image.PropertyKey.IMAGE_WIDTH,
image.PropertyKey.IMAGE_LENGTH,
image.PropertyKey.F_NUMBER
])
]);
// 5. 创建PixelMap(确保这一步成功)
this.pixelMap = await this.imageSource.createPixelMap();
if (!this.pixelMap) {
throw new Error('Failed to create PixelMap');
}
// 6. 保存到文件
await pixelMap2File(this.pixelMap, this.path);
this.getUIContext().getPromptAction().showToast({
message: $r('app.string.save_in_sandbox_success'),
duration: 2000
});
this.isShowSave = false;
} catch (error) {
this.handleSaveError(error as BusinessError);
}
}
四、所有代码,新建工程后,只修改Index.ets就可以
Index.ets代码
import { image } from '@kit.ImageKit';
import { PhotoPickerComponent, PickerController, photoAccessHelper, ReminderMode } from '@kit.MediaLibraryKit';
import { cameraPicker, camera } from '@kit.CameraKit';
import { picker } from '@kit.CoreFileKit';
import { promptAction } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { copyImg2Sandbox, pixelMap2File } from '../common/utils/Utils';
const TAG = 'IMAGE_APP';
@Entry
@Component
struct Index {
@State path: string = this.getUIContext().getHostContext()!.filesDir + '/image.jpg';
@State pixelMapPath: string = this.getUIContext().getHostContext()!.filesDir + '/pixelMap.jpg';
@State imageUri: string | undefined = undefined;
@State imageSource: image.ImageSource | undefined = undefined;
@State pixelMap: image.PixelMap | undefined = undefined;
@State isShowGet: boolean = false;
@State isShowPicker: boolean = false;
@State isShowSave: boolean = false;
@State pickerController: PickerController = new PickerController();
async saveImageToSandbox() {
// 1. 检查图片URI
if (!this.imageUri) {
this.getUIContext().getPromptAction().showToast({
message: $r('app.string.no_image_alert'),
duration: 2000
});
return;
}
try {
// 2. 等待图片复制到沙箱
await copyImg2Sandbox(this.imageUri, this.path);
// 3. 创建ImageSource
this.imageSource = image.createImageSource(this.path);
// 4. 并行获取图片信息
await Promise.all([
new Promise<void>((resolve, reject) => {
this.imageSource!.getImageInfo((error, info) => {
error ? reject(error) : resolve();
});
}),
this.imageSource.getImageProperties([
image.PropertyKey.IMAGE_WIDTH,
image.PropertyKey.IMAGE_LENGTH,
image.PropertyKey.F_NUMBER
])
]);
// 5. 创建PixelMap(确保这一步成功)
this.pixelMap = await this.imageSource.createPixelMap();
if (!this.pixelMap) {
throw new Error('Failed to create PixelMap');
}
// 6. 保存到文件
await pixelMap2File(this.pixelMap, this.path);
this.getUIContext().getPromptAction().showToast({
message: $r('app.string.save_in_sandbox_success'),
duration: 2000
});
this.isShowSave = false;
} catch (error) {
this.handleSaveError(error as BusinessError);
}
}
// 错误处理方法
private handleSaveError(error: BusinessError) {
hilog.error(0x0000, TAG, `保存失败: ${error.code}, ${error.message}`);
let message = "save_failed";
if (error.message.includes('createPixelMap')) {
message = "pixelmap_creation_failed";
} else if (error.message.includes('copyImg2Sandbox')) {
message = "copy_failed";
}
this.getUIContext().getPromptAction().showToast({
message,
duration: 2000
});
}
build() {
Navigation() {
Column() {
Image(this.imageUri)
.height(400)
.margin({ top: 16 })
Column({ space: 12 }) {
Button("打开相册照片")
.width('100%')
.height(40)
.onClick(async () => {
try {
let PhotoSelectOptions = new photoAccessHelper.PhotoSelectOptions();
PhotoSelectOptions.MIMEType = photoAccessHelper.PhotoViewMIMETypes.IMAGE_TYPE;
PhotoSelectOptions.maxSelectNumber = 1;
let photoPicker = new photoAccessHelper.PhotoViewPicker();
photoPicker.select(PhotoSelectOptions).then((PhotoSelectResult: photoAccessHelper.PhotoSelectResult) => {
this.imageUri = PhotoSelectResult.photoUris[0] ? PhotoSelectResult.photoUris[0] : this.imageUri;
hilog.info(0x0000, TAG, 'PhotoViewPicker.select succeed, uri: ' + JSON.stringify(PhotoSelectResult));
}).catch((err: BusinessError) => {
hilog.error(0x0000, TAG, `PhotoViewPicker.select failed, error: ${err.code}, ${err.message}`);
});
} catch (error) {
let err: BusinessError = error as BusinessError;
hilog.error(0x0000, TAG, `PhotoViewPicker failed, error: ${err.code}, ${err.message}`);
}
this.isShowGet = false;
})
Button("相机拍摄照片")
.width('100%')
.height(40)
.onClick(async () => {
// [Start pick_file]
try {
let pickerProfile: cameraPicker.PickerProfile =
{ cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK };
//Select the action of pulling up the camera to take pictures.
let pickerResult: cameraPicker.PickerResult = await cameraPicker.pick(this.getUIContext().getHostContext(),
[cameraPicker.PickerMediaType.PHOTO], pickerProfile);
//Return the photo uri to the application.
this.imageUri = pickerResult.resultUri ? pickerResult.resultUri : this.imageUri;
hilog.info(0x0000, TAG, 'cameraPicker.pick succeed, uri: ' + JSON.stringify(pickerResult));
} catch (error) {
let err = error as BusinessError;
hilog.error(0x0000, TAG, `cameraPicker.pick failed, error: ${err.code}, ${err.message}`);
}
// [End pick_file]
this.isShowGet = false;
})
Button("保存照片到APP目录")
.width('100%')
.height(40)
.onClick(async () => {
this.saveImageToSandbox();
})
}
.width('100%')
.height(150)
.padding({ left: 16, right: 16 })
.margin({ bottom: 16 })
.justifyContent(FlexAlign.SpaceBetween)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.SpaceBetween)
}
.width('100%')
.height('100%')
.title($r('app.string.title'))
}
}
五、显示效果
5.1 app图片和打开相册后图片

5.2 保存到APP目录后图片所存位置图,点击DevEco的右下角的 Device File Browser
