HarmonyOS 鸿蒙Next中如何写入exif信息

HarmonyOS 鸿蒙Next中如何写入exif信息 我有一个网络图片,需要下载下来添加exif信息并使用SaveButton保存到相册中,代码应该如何写

3 回复

编辑图片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)
  }
}

注意事项:

  1. 需要确保在module.json5中声明必要的权限:
"requestPermissions": [
  {
    "name": "ohos.permission.INTERNET"
  },
  {
    "name": "ohos.permission.WRITE_IMAGEVIDEO"
  }
]
  1. 实际使用时需要替换图片URL为真实的网络图片地址

  2. 根据实际需求调整EXIF属性,可以使用以下常用属性键:

    • IMAGE_WIDTH: 图片宽度
    • IMAGE_LENGTH: 图片高度
    • DATE_TIME: 拍摄日期
    • MAKE: 相机品牌
    • MODEL: 相机型号
    • 等等
  3. 如果需要更复杂的EXIF操作,可能需要使用专门的EXIF处理库

更多关于HarmonyOS 鸿蒙Next中如何写入exif信息的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,可使用@ohos.multimedia.image模块的ImagePackerImageSource处理EXIF信息。首先通过ImageSource.create创建图像源,使用getImageProperty获取现有属性,用modifyImageProperty修改EXIF字段(如GPS或拍摄时间),最后通过ImagePacker重新打包图像。支持标准EXIF标签,操作需在媒体文件权限范围内进行。

在HarmonyOS Next中,可以通过以下步骤实现下载网络图片、添加EXIF信息并保存到相册:

  1. 下载网络图片:使用@ohos.net.http模块发起HTTP请求获取图片数据。
  2. 解析和添加EXIF信息:通过@ohos.multimedia.image@ohos.file.fs处理图片元数据,使用第三方库(如exif-js)或原生API操作EXIF字段。
  3. 保存到相册:利用@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的原生支持有限,复杂操作需评估第三方库兼容性。
回到顶部