HarmonyOS鸿蒙Next应用开发中PixelMap转化为Uri的源码和步骤讲解

HarmonyOS鸿蒙Next应用开发中PixelMap转化为Uri的源码和步骤讲解

鸿蒙应用开发中PixelMap转化为Uri的源码和步骤讲解

3 回复

一、结论

鸿蒙中的PixelMap类型,其实类似于Android和IOS中的bitmap,是对图片数据信息进行描述的一种逻辑运算使用的图片类型。

而鸿蒙中的Uri类型,本质其实是带file头的文件存储地址,是用来指向文件存储路径的一个字符串,例如:

'file://com.example.temptest/data/storage/el2/base/haps/entry/files/test.jpg';

去掉file头,其实就是path类型了。

二、代码实现和详细解释

首先这两种类型是无法直接转化的,经过刚才的类型介绍,我们知道Uri是文件的存储路径,如果已经有存储路径说明进行了file操作。那答案显而易见了,我们只需要将PixelMap进行图片存储到沙箱中,得到File之后再拿到Uri即可。

  /**
   * PixelMap转为图片Uri
   * @param pixelMap
   * @returns
   */
  public async PixelMapToUri(pixelMap: PixelMap){
    // 将图片保存到沙箱
    // 先获取其应用沙箱路径
    let fileDir = getContext().getApplicationContext().filesDir;
    // 创建图片目录
    let fileSavePath = fileDir + "image";
    let res = fs.accessSync(fileSavePath);
    if(res){
      fs.mkdirSync(fileSavePath, true);
    }
    let packer = image.createImagePacker();
    let packOpts: image.PackingOption = {
      // 目标格式。当前只支持"image/jpeg"、"image/webp"、"image/png"和"image/heif"12+(不同硬件设备支持情况不同)。
      // 因为jpeg不支持透明通道,若使用带透明通道的数据编码jpeg格式,透明色将变为黑色。
      format: "image/png",
      // JPEG编码中设定输出图片质量的参数,取值范围为0-100。0质量最低,100质量最高,质量越高生成图片所占空间越大。
      quality: 100
    }
	fileSavePath = fileSavePath  + new Date().getTime() + ".png",
    // fileSavePath 打开文件的应用沙箱路径或URI,使用URI作为入参时,仅支持打开文件。
		
    //开文件的选项,必须指定如下选项中的一个,默认以只读方式打开:
    // - OpenMode.READ_ONLY(0o0):只读打开。
    //
    // - OpenMode.WRITE_ONLY(0o1):只写打开。
    //
    // - OpenMode.READ_WRITE(0o2):读写打开。
    //
    // 给定如下功能选项,以按位或的方式追加,默认不给定任何额外选项:
    //
    // - OpenMode.CREATE(0o100):若文件不存在,则创建文件。(path为URI时不支持创建文件)
    //
    //   - OpenMode.TRUNC(0o1000):如果文件存在且文件具有写权限,则将其长度裁剪为零。
    //
    // - OpenMode.APPEND(0o2000):以追加方式打开,后续写将追加到文件末尾。
    //
    // - OpenMode.NONBLOCK(0o4000):如果path指向FIFO、块特殊文件或字符特殊文件,则本次打开及后续 IO 进行非阻塞操作。
    //
    // - OpenMode.DIR(0o200000):如果path不指向目录,则出错。不允许附加写权限。
    //
    // - OpenMode.NOFOLLOW(0o400000):如果path指向符号链接,则出错。
    //
    // - OpenMode.SYNC(0o4010000):以同步IO的方式打开文件。
    let targetFile = fs.openSync(fileSavePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE);
    let fd = targetFile.fd;
    await packer.packToFile(pixelMap, fd, packOpts);
    fs.closeSync(fd);
    let targetUri = fileUri.getUriFromPath(targetFile.path);
    return targetUri;
  }

更多关于HarmonyOS鸿蒙Next应用开发中PixelMap转化为Uri的源码和步骤讲解的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS Next中,将PixelMap转化为Uri需要使用ImagePackerImageSource。步骤如下:

  1. 通过ImagePacker创建实例,调用packing方法将PixelMap编码为ArrayBuffer。
  2. 使用ImageSource.createImageSource从ArrayBuffer创建ImageSource。
  3. 调用ImageSource的getDataUri方法获取Data URI字符串。
  4. 若需Uri对象,使用globalThis.uriUtils.createUri进行转换。

关键代码:

let packer = image.createImagePacker();
let arrayBuffer = await packer.packing(pixelMap, { format:"image/jpeg" });
let imageSource = image.createImageSource(arrayBuffer);
let dataUri = await imageSource.getDataUri();
let uri = globalThis.uriUtils.createUri(dataUri);

在HarmonyOS Next应用开发中,将PixelMap对象转换为Uri对象是一个常见的需求,主要用于图像数据的持久化存储或跨进程传递。以下是核心的源码实现和步骤讲解。

核心步骤与源码

  1. 获取ImagePacker实例:使用ImagePacker类来打包PixelMap为图片格式。
  2. 打包PixelMap:将PixelMap打包为支持的文件格式(如JPEG、PNG)的ArrayBuffer
  3. 写入临时文件:将ArrayBuffer数据写入应用临时目录(tempDir)下的文件。
  4. 生成Uri:基于临时文件路径创建Uri。

示例代码

import image from '@ohos.multimedia.image';
import fs from '@ohos.file.fs';
import common from '@ohos.app.ability.common';

async function pixelMapToUri(pixelMap: image.PixelMap, context: common.UIAbilityContext): Promise<string | undefined> {
  // 1. 创建ImagePacker实例
  let imagePackerApi = image.createImagePacker();

  // 2. 打包选项:设置格式和质量
  let options: image.PackingOption = { format: "image/jpeg", quality: 98 }; // 也可使用"image/png"

  // 3. 将PixelMap打包为ArrayBuffer
  let arrayBuffer: ArrayBuffer = await imagePackerApi.packing(pixelMap, options);

  // 4. 定义临时文件路径(应用临时目录 + 唯一文件名)
  let tempDir = context.filesDir; // 或使用 context.tempDir
  let filePath = tempDir + `/${Date.now()}.jpg`; // 根据格式调整后缀

  // 5. 将ArrayBuffer写入文件
  let file = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
  fs.writeSync(file.fd, arrayBuffer);
  fs.closeSync(file);

  // 6. 生成并返回Uri
  // 注意:直接使用文件路径可能无法直接作为Uri传递给某些组件。
  // 通常需要转换为合适的Uri格式,例如使用`FileUri`模块(如果可用)或直接使用文件路径字符串。
  // 这里返回文件路径,实际使用时可能需要根据目标API封装为Uri对象。
  return `file://${filePath}`; // 或返回 filePath,具体取决于使用场景
}

关键点说明

  • 格式与质量PackingOption中的formatquality参数决定了输出图像的格式和压缩质量(JPEG格式有效)。
  • 存储位置:示例使用了应用的文件目录(filesDir),你也可以根据需求选择临时目录(tempDir),注意临时目录可能被系统清理。
  • Uri的使用:生成的file://路径Uri通常可用于<Image>组件显示,或通过picker等系统能力分享。如果目标API要求特定的Uri格式(如dataability://internal://),需根据具体场景调整。
  • 资源释放:确保不再需要时删除临时文件,避免存储空间浪费。

注意事项

  • 该过程涉及文件I/O操作,建议在异步函数中执行。
  • 写入文件路径需确保应用具有相应的文件访问权限(ohos.permission.READ_MEDIAohos.permission.WRITE_MEDIA 等,根据目标目录而定)。
  • HarmonyOS Next的API可能存在版本差异,开发时请参考对应版本的官方API文档。

通过以上步骤,你可以将PixelMap对象转换为一个可通过Uri引用的图像文件。

回到顶部