HarmonyOS鸿蒙Next中Uint8Array转换成PixelMap失败,求助
HarmonyOS鸿蒙Next中Uint8Array转换成PixelMap失败,求助 从另一个进程传过来的base64格式图片流(图片为PNG),拿到后进行base64解码,解码后的byteLength和base64编码前一致。创建ImageResource后创建PixalMap,得到如下报错
代码如下
Log.i(TAG, 'vcode base64=' + base64Buffer)
let base64Helper = new util.Base64Helper()
let uint8Array: Uint8Array = base64Helper.decodeSync(base64Buffer)
Log.i(TAG, 'vcode buffer len=' + uint8Array.byteLength)
let imageSource = image.createImageSource(uint8Array.buffer)
Log.i(TAG, 'createImageSource finished')
let options: image.InitializationOptions = {
'alphaType': 0, // 透明度
'editable': false, // 是否可编辑
'pixelFormat': 3, // 像素格式
'scaleMode': 1, // 缩略值
'size': { height: 40, width: 80 } // 创建图片大小
}
// 生成 PixelMap
imageSource.createPixelMap(options).then((pixelMap: image.PixelMap) => {
Log.i(TAG, 'createPixelMap finished')
AppStorage.setOrCreate(AppStorageKey.GRAPHIC_VCODE, pixelMap)
}).catch((e: BusinessError) => {
Log.i(TAG, 'createPixelMap failed, ' + JSON.stringify(e))
})
更多关于HarmonyOS鸿蒙Next中Uint8Array转换成PixelMap失败,求助的实战教程也可以访问 https://www.itying.com/category-93-b0.html
从打印结果看,输出了:
'createPixelMap finished'
这应该说明转换是成功的。 报错的信息,很可能是这一句:
AppStorage.setOrCreate(AppStorageKey.GRAPHIC_VCODE, pixelMap)
从API version 12开始,AppStorage支持Map、Set、Date类型,支持null、undefined以及联合类型。
不应该用 AppStorage 去存储 PixelMap 类型的对象。
更多关于HarmonyOS鸿蒙Next中Uint8Array转换成PixelMap失败,求助的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
建议楼主将 PixelMap 保存为图片放在沙箱中使用,PixelMap存储在内存中占用存储过大,出现过多的PixelMap存储在内存中会导致UI卡顿
const resourceMgr: resourceManager.ResourceManager = this.context.resourceManager;
// beer.jpeg为rawfile文件下的图片名,可根据自身需求修改使用。
const fileData: Uint8Array = await resourceMgr.getRawFileContent('beer.jpeg');
let buffer = new Uint8Array(fileData).buffer as object as ArrayBuffer;
let imageResource = image.createImageSource(buffer);
let opts: image.DecodingOptions = { editable: true };
this.pixel = await imageResource.createPixelMap(opts);
AppStorage.setOrCreate(AppStorageKey.GRAPHIC_VCODE, pixelMap)
AppStorage.setOrCreate方法无法直接存储PixelMap对象
可以将PixelMap保存为本地文件后,存储文件路径到AppStorage
感谢您的提问,这边复现了下并没有出现pixmapNapi unwrapped is nullptr问题,为了更快解决您的问题,麻烦请补充以下信息:
复现代码(如最小复现demo);
版本信息(如:开发工具、手机系统版本信息);
从代码和错误信息来看,核心问题在于createPixelMap时指定的size与原始图片的实际尺寸不匹配。
错误码401通常表示参数错误。在你的代码中,InitializationOptions里设置的size是固定的{ height: 40, width: 80 }。createPixelMap方法会尝试将图片解码并缩放到这个指定尺寸。如果传入的PNG图片流的实际尺寸与这个{40, 80}的宽高比差异巨大,或者图片本身无法正确解码到这个尺寸,就会抛出这个异常。
解决方案是使用图片解码后的自然尺寸,或者先获取图片信息再决定缩放尺寸。建议修改如下:
- 先获取图片尺寸:使用
createImageSource后,先调用getImageInfo()获取图片的原始宽高。 - 动态计算目标尺寸或使用原始尺寸:根据获取到的
imageInfo来设置options中的size,或者使用imageInfo.size直接作为目标尺寸,避免宽高比不匹配导致的解码失败。
修改后的核心代码段示例:
let imageSource = image.createImageSource(uint8Array.buffer);
// 首先获取图片信息
imageSource.getImageInfo().then((imageInfo: image.ImageInfo) => {
Log.i(TAG, `Original image size: width=${imageInfo.size.width}, height=${imageInfo.size.height}`);
let options: image.InitializationOptions = {
'alphaType': 0,
'editable': false,
'pixelFormat': 3,
'scaleMode': 1,
// 使用获取到的原始尺寸,或基于此计算你的目标尺寸(如按比例缩放)
'size': imageInfo.size // 直接使用原始尺寸通常是最安全的
// 或者按需缩放: 'size': { height: yourTargetHeight, width: yourTargetWidth }
};
// 生成 PixelMap
return imageSource.createPixelMap(options);
}).then((pixelMap: image.PixelMap) => {
Log.i(TAG, 'createPixelMap finished');
AppStorage.setOrCreate(AppStorageKey.GRAPHIC_VCODE, pixelMap);
}).catch((e: BusinessError) => {
Log.i(TAG, 'Error: ' + JSON.stringify(e));
});
关键点:确保createPixelMap的size参数与图片内容兼容。对于来自网络或进程间通信的图片,其尺寸是未知的,直接指定一个固定尺寸风险很高。先通过getImageInfo()探明尺寸是标准做法。
另外,检查uint8Array.buffer包含的数据是否是完整的、未损坏的PNG文件数据。你已确认byteLength一致,这步通常是正确的。问题焦点应放在尺寸参数的处理上。

