【HarmonyOS 】ArrayBuffer转Base64,Base64转ArrayBuffer,Uri转ArrayBuff,PixelMap转ArrayBuffer,图片Uri转为PixelMap 在HarmonyOS开发中ArrayBuffer、Base64、Uri和PixelMap之间的相互转换是处理图片和二进制数据的常见操作。以下将结合官方API和社区实践详解这几种核心转换的实现方法。一、核心概念与工具准备在开始转换之前先明确几个核心概念这有助于理解后续的转换逻辑ArrayBuffer代表通用的、固定长度的原始二进制数据缓冲区。在HarmonyOS中它是一种可转移对象在线程间传递时不会拷贝数据能有效减少内存占用提升性能。Uint8Array类型化数组用于操作ArrayBuffer中的数据。Base64编解码和文件读取等操作通常需要先处理Uint8Array。Base64一种基于64个可打印字符来表示二进制数据的编码方法常用于在文本协议如JSON中传输图片数据。Uri资源的统一资源标识符通常以file://开头用于指向文件系统中的某个资源如图片。PixelMap图像解码后的无压缩位图格式用于图像显示或进一步处理如裁剪、缩放类似于Android的Bitmap。准备工作导入必要模块在编写代码前需要导入以下核心模块typescriptimport { util } from kit.ArkTS; // 提供Base64编解码能力 import { image } from kit.ImageKit; // 提供图片处理能力如创建PixelMap import { fileIo as fs } from kit.CoreFileKit; // 提供文件读写能力 import { fileUri } from kit.CoreFileKit; // 提供Uri与路径的转换能力二、ArrayBuffer 与 Base64 互转这是最基础的转换官方提供了util.Base64Helper类来轻松实现。1. ArrayBuffer 转 Base64将ArrayBuffer转为Base64字符串常用于网络传输或将图片数据嵌入到文本中。typescript/** * ArrayBuffer转Base64 * param buffer ArrayBuffer对象 * returns Base64字符串 */ arrayBuffer2Base64(buffer: ArrayBuffer): string { // 1. 将ArrayBuffer转换为Uint8Array let temp new Uint8Array(buffer); // 2. 创建Base64Helper实例 let helper new util.Base64Helper(); // 3. 同步编码为Base64字符串 let res helper.encodeToStringSync(temp); return res; }来源HarmonyOS社区实践该方法直接使用官方API稳定可靠。2. Base64 转 ArrayBuffer将接收到的Base64字符串还原为ArrayBuffer以便进行后续的文件写入或图片解码操作。typescript/** * Base64转ArrayBuffer * param base64Str Base64字符串 * returns ArrayBuffer */ base642Buffer(base64Str: string): ArrayBuffer { // 1. 创建Base64Helper实例 let helper new util.Base64Helper(); // 2. 解码为Uint8Array let temp: Uint8Array helper.decodeSync(base64Str); // 3. 从Uint8Array中获取ArrayBuffer let res: ArrayBuffer temp.buffer as ArrayBuffer; return res; }来源编码与解码是对称操作同样依赖官方util.Base64Helper实现。实际开发中Base64字符串可能会带有data:image/jpg;base64,前缀编码前需要去除。三、图片 Uri 转 ArrayBuffer当需要直接操作文件如计算MD5、上传文件时需要将Uri指向的文件内容读入ArrayBuffer。1. 通过文件流读取此方法通过fs.openSync打开文件然后同步读取内容。对于大文件建议使用异步API避免阻塞主线程。typescriptimport { fileIo as fs } from kit.CoreFileKit; /** * 图片Uri转ArrayBuffer (同步方式) * param uri 图片的Uri例如 file:///data/storage/el2/base/haps/entry/files/test.jpg * returns ArrayBuffer */ imageUri2BufferSync(uri: string): ArrayBuffer { // 1. 以只读方式打开文件 let file fs.openSync(uri, fs.OpenMode.READ_ONLY); // 2. 获取文件大小 let stat fs.statSync(uri); // 3. 根据文件大小创建ArrayBuffer let buffer new ArrayBuffer(stat.size); // 4. 读取文件内容到buffer let readLen fs.readSync(file.fd, buffer); // 5. 关闭文件 fs.closeSync(file); return buffer; }来源该方法基于社区和官方开发者问答是HarmonyOS中最常用的文件转ArrayBuffer方式。2. 注意Uri格式如果获取到的Uri不带file://前缀而是/data/...这样的路径需要先使用fileUri.getUriFromPath(path)将其转换为标准Uri再执行上述操作。转换后readSync方法同样支持传入文件路径而非fd。四、PixelMap 与 ArrayBuffer 互转在实际业务中可能需要将PixelMap保存为文件、压缩或进行像素级处理这时就需要与ArrayBuffer互转。1. PixelMap 转 ArrayBuffer方法一是通过PixelMap的readPixelsToBuffer或readPixelsToBufferSync直接读取像素数据。注意此方法得到的是原始像素数据如RGBA格式而非压缩后的图片文件如JPEG。typescript/** * PixelMap转ArrayBuffer (原始像素数据) * param pixelMap PixelMap对象 * returns 包含原始像素的ArrayBuffer */ pixelMap2ArrayBuffer(pixelMap: image.PixelMap): ArrayBuffer { // 1. 创建一个与像素数据大小匹配的ArrayBuffer let buffer new ArrayBuffer(pixelMap.getPixelBytesNumber()); // 2. 将像素数据同步读取到buffer中 pixelMap.readPixelsToBufferSync(buffer); return buffer; }来源部分开发者反映直接保存原始像素数据得到的文件可能是无效的图片。因此更常见的做法是通过ImagePacker将PixelMap打包成JPEG或PNG格式的ArrayBuffer。typescript/** * PixelMap转ArrayBuffer (压缩编码后) * param pixelMap PixelMap对象 * param format 目标格式如 image/jpeg * param quality 图片质量 0-100 * returns 压缩后的图片数据ArrayBuffer */ async pixelMap2PackedBuffer(pixelMap: image.PixelMap, format: string image/jpeg, quality: number 100): PromiseArrayBuffer { const imagePackerApi image.createImagePacker(); const packOpts: image.PackingOption { format: format, quality: quality }; // 将PixelMap压缩并打包为ArrayBuffer const data: ArrayBuffer await imagePackerApi.packing(pixelMap, packOpts); return data; }来源这是鸿蒙官方推荐的将PixelMap编码为JPEG/PNG等格式图片的标准方法。2. ArrayBuffer 转 PixelMap此操作通常用于将解码后的图片数据或通过其他方式获取的原始RGB数据转换为PixelMap以供显示。typescript/** * ArrayBuffer转PixelMap * param buffer 图片文件数据或原始像素数据的ArrayBuffer * param opts 初始化选项用于指定尺寸、像素格式等 * returns PixelMap对象 */ async buffer2PixelMap(buffer: ArrayBuffer, opts?: image.InitializationOptions): Promiseimage.PixelMap { // 1. 从ArrayBuffer创建ImageSource let imageSource image.createImageSource(buffer); // 2. 从ImageSource创建PixelMap let pixelMap await imageSource.createPixelMap(opts); return pixelMap; }来源此流程是官方文档介绍的从文件缓冲区创建PixelMap的标准方式。当处理原始RGB数据时需要明确设置opts中的srcPixelFormat和pixelFormat等参数。五、图片 Uri 转 PixelMap这是展示图片的常见前置步骤通过Uri直接创建PixelMap避免文件读写的中间环节。typescriptimport { fileIo as fs } from kit.CoreFileKit; /** * 图片Uri转PixelMap * param uri 图片的Uri * returns PixelMap对象 */ async imageUri2PixelMap(uri: string): Promiseimage.PixelMap { // 1. 以只读方式打开Uri指向的文件获取文件描述符(fd) let file fs.openSync(uri, fs.OpenMode.READ_ONLY); // 2. 从文件描述符创建ImageSource let imageSource image.createImageSource(file.fd); // 3. 从ImageSource创建PixelMap可传入解码选项 let pixelMap await imageSource.createPixelMap({ editable: true, desiredPixelFormat: image.PixelMapFormat.RGBA_8888 }); // 4. 关闭文件 fs.closeSync(file); return pixelMap; }来源这是HarmonyOS官方及开发者社区最常用、最高效的Uri转PixelMap方案。其中createImageSource支持传入fd从而直接读取文件内容。六、PixelMap 转 Uri (保存到沙箱)如果只有PixelMap对象而需要获取其Uri如用于分享、保存则必须先将PixelMap保存为文件再获取文件的Uri。typescript/** * PixelMap转图片Uri * param pixelMap PixelMap对象 * param fileName 保存的文件名包含后缀如 image.png * returns 保存后的图片Uri */ async pixelMap2Uri(pixelMap: image.PixelMap, fileName: string): Promisestring { // 1. 获取应用沙箱的files目录 let fileDir getContext().filesDir; let filePath ${fileDir}/${fileName}; // 2. 创建ImagePacker将PixelMap打包为图片文件 const imagePackerApi image.createImagePacker(); const packOpts: image.PackingOption { format: image/png, // 根据后缀灵活选择 quality: 100 }; // 3. 以创建读写模式打开文件 let file fs.openSync(filePath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE); // 4. 将PixelMap打包并直接写入文件 await imagePackerApi.packToFile(pixelMap, file.fd, packOpts); // 5. 关闭文件 fs.closeSync(file); // 6. 通过路径生成Uri let targetUri fileUri.getUriFromPath(filePath); return targetUri; }来源此方法结合了文件操作和ImagePacker是社区中PixelMap转Uri的标准方案。packToFile是性能最优的方式避免了先获取ArrayBuffer再写入文件的中间步骤。总结与最佳实践Base64与ArrayBuffer互转直接使用util.Base64Helper简单可靠。Uri与ArrayBuffer互转核心是文件读写。Uri是路径ArrayBuffer是内容通过fs.openSync和fs.readSync实现。PixelMap与ArrayBuffer互转获取原始像素使用pixelMap.readPixelsToBufferSync。获取编码后的图片数据使用ImagePacker.packing推荐这样得到的ArrayBuffer可以直接保存为图片文件。Uri与PixelMap互转Uri - PixelMap通过文件描述符fd创建ImageSource再创建PixelMap高效直接。PixelMap - Uri需要先将PixelMap通过ImagePacker.packToFile保存为文件再通过fileUri.getUriFromPath生成Uri。