HarmonyOS 鸿蒙Next中如何写入exif信息
HarmonyOS 鸿蒙Next中如何写入exif信息 我有一个网络图片,需要下载下来添加exif信息并使用SaveButton保存到相册中,代码应该如何写
编辑图片EXIF信息-图片编辑和处理-图片开发指导(ArkTS)-Image Kit(图片处理服务)-媒体 - 华为HarmonyOS开发者
使用保存控件-使用安全控件-程序访问控制-安全-系统 - 华为HarmonyOS开发者
批量下载保存图片和视频-关键场景示例-实用工具类行业实践-行业实践 - 华为HarmonyOS开发者
以下是完整代码:
import { http } from '@kit.NetworkKit';
import { image } from '@kit.ImageKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { common } from '@kit.AbilityKit';
import { fileIo } from '@kit.CoreFileKit';
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { promptAction } from '@kit.ArkUI';
@Entry
@Component
struct Index {
// 保存下载的图片临时文件路径
@State tempFilePath: string = '';
// 保存ImageSource实例用于修改EXIF
private imageSource: image.ImageSource | null = null;
// 获取UIAbilityContext
private context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;
// SaveButton选项配置
@State saveButtonOptions: SaveButtonOptions = {
icon: SaveIconStyle.FULL_FILLED,
text: SaveDescription.SAVE_IMAGE,
buttonType: ButtonType.Capsule
};
aboutToAppear() {
// 在组件出现时下载图片
this.downloadImage();
}
// 下载网络图片
async downloadImage() {
try {
let httpRequest = http.createHttp();
// 替换为实际图片URL
let url = ' https://www.example.com/image.jpg ';
httpRequest.request(url, (error: BusinessError, data: http.HttpResponse) => {
if (error) {
console.error(`下载失败: 错误码: ${error.code}, 错误信息: ${error.message}`);
return;
}
if (data.result instanceof ArrayBuffer) {
let arrayBuffer = data.result as ArrayBuffer;
// 保存为临时文件
this.saveToTempFile(arrayBuffer);
} else {
console.error('下载的数据不是ArrayBuffer格式');
}
});
} catch (error) {
console.error(`下载请求失败: ${JSON.stringify(error)}`);
}
}
// 将ArrayBuffer保存为临时文件
async saveToTempFile(arrayBuffer: ArrayBuffer) {
try {
let tempDir = this.context.filesDir;
let fileName = `temp_${Date.now()}.jpg`;
this.tempFilePath = `${tempDir}/${fileName}`;
let file = fileIo.openSync(this.tempFilePath, fileIo.OpenMode.CREATE | fileIo.OpenMode.READ_WRITE);
fileIo.writeSync(file.fd, arrayBuffer);
fileIo.closeSync(file.fd);
console.info('图片已保存到临时文件: ' + this.tempFilePath);
// 创建ImageSource实例
this.imageSource = image.createImageSource(this.tempFilePath);
// 添加EXIF信息
await this.addExifInfo();
} catch (error) {
console.error(`保存临时文件失败: ${JSON.stringify(error)}`);
}
}
// 添加EXIF信息
async addExifInfo() {
if (!this.imageSource) {
console.error('ImageSource未初始化');
return;
}
try {
// 示例:修改图片宽度和长度属性(实际EXIF属性键需参考文档)
let records: Record<image.PropertyKey, string | null> = {
[image.PropertyKey.IMAGE_WIDTH]: "1024", // 示例属性
[image.PropertyKey.IMAGE_LENGTH]: "768", // 示例属性
// 可以添加其他EXIF属性,如日期、相机型号等
};
await this.imageSource.modifyImageProperties(records);
console.info('EXIF信息添加成功');
} catch (error) {
console.error(`添加EXIF失败: ${JSON.stringify(error)}`);
}
}
// 保存图片到相册
async saveToAlbum() {
if (!this.imageSource) {
promptAction.showToast({ message: '请先下载图片', duration: 2000 });
return;
}
try {
// 编码图片为JPEG格式
let imagePacker = image.createImagePacker();
let options: image.PackingOptions = {
format: "image/jpeg",
quality: 100
};
let data = await imagePacker.packing(this.imageSource, options);
// 使用photoAccessHelper保存到相册
let phAccessHelper = photoAccessHelper.getPhotoAccessHelper(this.context);
let uri = await phAccessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg');
let file = await fileIo.open(uri, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
await fileIo.write(file.fd, data);
await fileIo.close(file.fd);
promptAction.showToast({ message: '图片已保存到相册', duration: 2000 });
console.info('图片已保存到相册: ' + uri);
} catch (error) {
console.error(`保存到相册失败: ${JSON.stringify(error)}`);
promptAction.showToast({ message: '保存失败', duration: 2000 });
}
}
build() {
Column() {
// 这里可以显示下载的图片(可选)
// Image(this.imageSource) ...
// SaveButton组件
SaveButton(this.saveButtonOptions)
.onClick((event: ClickEvent, result: SaveButtonOnClickResult) => {
if (result === SaveButtonOnClickResult.SUCCESS) {
this.saveToAlbum();
} else {
promptAction.showToast({ message: '保存权限获取失败', duration: 2000 });
}
})
.margin(20)
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
注意事项:
- 需要确保在
module.json5
中声明必要的权限:
"requestPermissions": [
{
"name": "ohos.permission.INTERNET"
},
{
"name": "ohos.permission.WRITE_IMAGEVIDEO"
}
]
-
实际使用时需要替换图片URL为真实的网络图片地址
-
根据实际需求调整EXIF属性,可以使用以下常用属性键:
IMAGE_WIDTH
: 图片宽度IMAGE_LENGTH
: 图片高度DATE_TIME
: 拍摄日期MAKE
: 相机品牌MODEL
: 相机型号- 等等
-
如果需要更复杂的EXIF操作,可能需要使用专门的EXIF处理库
更多关于HarmonyOS 鸿蒙Next中如何写入exif信息的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,可使用@ohos.multimedia.image
模块的ImagePacker
和ImageSource
处理EXIF信息。首先通过ImageSource.create
创建图像源,使用getImageProperty
获取现有属性,用modifyImageProperty
修改EXIF字段(如GPS或拍摄时间),最后通过ImagePacker
重新打包图像。支持标准EXIF标签,操作需在媒体文件权限范围内进行。
在HarmonyOS Next中,可以通过以下步骤实现下载网络图片、添加EXIF信息并保存到相册:
- 下载网络图片:使用
@ohos.net.http
模块发起HTTP请求获取图片数据。 - 解析和添加EXIF信息:通过
@ohos.multimedia.image
和@ohos.file.fs
处理图片元数据,使用第三方库(如exif-js)或原生API操作EXIF字段。 - 保存到相册:利用
@ohos.file.photoAccessHelper
将处理后的图片写入相册。
示例代码框架如下(需根据实际依赖调整):
import http from '@ohos.net.http';
import image from '@ohos.multimedia.image';
import phAccessHelper from '@ohos.file.photoAccessHelper';
// 1. 下载图片
async function downloadImage(url: string): Promise<image.PixelMap> {
// 实现HTTP请求并转换为PixelMap
}
// 2. 添加EXIF信息(需依赖EXIF操作库)
async function addExif(pixelMap: image.PixelMap, exifData: Object): Promise<image.PixelMap> {
// 修改EXIF逻辑(当前HarmonyOS EXIF API可能受限,建议通过第三方JS库处理)
}
// 3. 保存到相册
async function saveToAlbum(pixelMap: image.PixelMap) {
const photoAccessHelper = phAccessHelper.getPhotoAccessHelper(context);
const createOption = { title: 'processed_image.jpg' };
const uri = await photoAccessHelper.createAsset(createOption);
// 将PixelMap写入uri对应的文件
}
// 整合流程
async function processImage() {
const pixelMap = await downloadImage('https://example.com/image.jpg');
const updatedPixelMap = await addExif(pixelMap, { /* EXIF字段 */ });
await saveToAlbum(updatedPixelMap);
}
注意事项:
- EXIF处理可能需要结合原生能力与JS库(如exif-parser或exif-js的适配)。
- 确保声明网络权限(
ohos.permission.INTERNET
)和存储权限(ohos.permission.WRITE_IMAGEVIDEO
)。 - 当前HarmonyOS对EXIF的原生支持有限,复杂操作需评估第三方库兼容性。