HarmonyOS 图片与 Base64 互转:ImageUtil pixelMapToBase64Str 实战
文章目录
- 前言
- packingFromPixelMap:PixelMap 打包成二进制
- pixelMapToBase64Str:PixelMap 转 Base64 字符串
- base64ToPixelMap:Base64 转回 PixelMap
- packingFromImageSource:从 ImageSource 打包
- 理解 PNG vs JPEG 的字节大小差异
- 写在最后
前言
近期发现一款很有意思的HarmonyOS 三方库, 地址 @pura/harmony-utils(V1.4.0) , 作者是"桃花镇童长老", 我这里也是直接通过该作者公布的源码进行案例编写进行,写了到目前写了一部分demo ,感觉确实很有帮助,这里呢也是开始写一个系列的演示demo 供大家参考。如有帮助可以在OpenHarmony中进行下载安装进行使用哦
案例demo导航展示
↓↓↓↓↓↓接下来言归正传 ↓↓↓↓
图片和 Base64 互转是一个高频需求:上传图片到后台接口时可能需要传 Base64 字符串,从接口拿到 Base64 数据要在界面上显示时,需要先转回 PixelMap。
这篇把pixelMapToBase64Str、base64ToPixelMap、packingFromPixelMap这几个方法讲清楚。
packingFromPixelMap:PixelMap 打包成二进制
在转 Base64 之前,先理解packingFromPixelMap——它是很多图片操作的基础步骤。
packingFromPixelMap把 PixelMap 编码成指定格式的图片二进制数据(ArrayBuffer):
// 打包成 PNGconstpm=awaitthis.makeTestPixelMap(180,100,220,80,80);constpackOpts:image.PackingOption={format:'image/png',quality:100};constbuf=awaitImageUtil.packingFromPixelMap(pm,packOpts);this.addLog(`packingFromPixelMap(png):${buf.byteLength}bytes`);// 打包成 JPEG,质量 80constpm=awaitthis.makeTestPixelMap(50,100,200,80,80);constpackOpts:image.PackingOption={format:'image/jpeg',quality:80};constbuf=awaitImageUtil.packingFromPixelMap(pm,packOpts);this.addLog(`packingFromPixelMap(jpeg,q=80):${buf.byteLength}bytes`);PackingOption的两个关键字段:
format:图片格式,'image/png'(无损)或'image/jpeg'(有损)quality:质量(1-100),PNG 格式下这个值不影响文件大小,JPEG 下影响明显
一般规律:同样内容的图片,JPEG 文件比 PNG 小很多,但 JPEG 有压缩损失。
pixelMapToBase64Str:PixelMap 转 Base64 字符串
这个方法封装了"打包 + Base64 编码"两步,直接给你一个 Base64 字符串:
// PNG 格式constpm=awaitthis.makeTestPixelMap(100,200,100,50,50);constb64=awaitImageUtil.pixelMapToBase64Str(pm,'image/png');this.previewBase64=b64.substring(0,60)+'...';this.addLog(`pixelMapToBase64Str(png):${b64.length}chars`);// JPEG 格式constpm=awaitthis.makeTestPixelMap(200,150,50,60,60);constb64=awaitImageUtil.pixelMapToBase64Str(pm,'image/jpeg');this.addLog(`pixelMapToBase64Str(jpeg):${b64.length}chars`);两个参数:
- PixelMap 对象
- 图片格式字符串(
'image/png'或'image/jpeg')
返回的是纯 Base64 字符串(不含data:image/png;base64,前缀)。
如果你要在 WebView 的 H5 页面里展示,需要自己拼接前缀:
constdataUrl=`data:image/png;base64,${b64}`;base64ToPixelMap:Base64 转回 PixelMap
方向反过来,把 Base64 字符串解码成 PixelMap:
// 先把 PixelMap 转成 Base64constpm=awaitthis.makeTestPixelMap(255,128,0,40,40);constb64=awaitImageUtil.pixelMapToBase64Str(pm,'image/png');// 再把 Base64 转回 PixelMapconstrestored=awaitImageUtil.base64ToPixelMap(b64);this.previewPixelMap=restored;this.previewLabel='base64 → PixelMap (橙色40×40)';constinfo=restored.getImageInfoSync();this.addLog(`base64ToPixelMap:${info.size.width}×${info.size.height}`);还原后的 PixelMap 尺寸信息应该和原来一致(40×40)。
这个方向的典型场景:后台接口返回 Base64 格式的图片,需要在Image组件里展示。
packingFromImageSource:从 ImageSource 打包
packingFromImageSource和packingFromPixelMap功能类似,区别是输入是ImageSource而不是PixelMap:
// 先把 PixelMap 打包成 PNG,再创建 ImageSourceconstpm=awaitthis.makeTestPixelMap(200,200,50,60,60);constpngBuf=awaitImageUtil.packingFromPixelMap(pm,{format:'image/png',quality:100});constsrc=ImageUtil.createImageSource(pngBuf);// 再从 ImageSource 打包成 JPEGconstopts:image.PackingOption={format:'image/jpeg',quality:90};constbuf=awaitImageUtil.packingFromImageSource(src,opts);this.addLog(`packingFromImageSource:${buf.byteLength}bytes`);这个用法的场景:从文件或网络得到了原始图片数据(非 PixelMap),需要转换格式。比如你有一个 PNG 文件的 ArrayBuffer,想转成 JPEG,就走这个流程:createImageSource(pngBuffer)→packingFromImageSource(src, {format: 'image/jpeg'})。
理解 PNG vs JPEG 的字节大小差异
演示代码展示了同一张图片打包成不同格式后的大小对比,这是理解图片压缩的直观方式。
一般来说:
- PNG:无损压缩,文件较大,适合截图、图标、需要透明度的图
- JPEG:有损压缩,文件较小,适合照片、自然图像
- quality 参数:仅对 JPEG 有效,数值越低文件越小,画质越差
写在最后
图片和 Base64 互转就两个核心方法:
pixelMapToBase64Str(pm, format):PixelMap → Base64 字符串base64ToPixelMap(b64):Base64 字符串 → PixelMap
packingFromPixelMap是它们的底层支撑,理解了打包过程,再看压缩相关的 API 就容易了。
下篇讲图片压缩:如何控制图片大小不超过目标体积。
