无需使用显示canvas从Uint8Array提取ImageData用于TensorFlow姿态估计
代码修复方案
错误原因
你代码的核心问题是context.drawImage()不支持直接传入Uint8Array类型的原始图片二进制数据,该方法仅接收Image元素、Canvas元素、ImageBitmap等可渲染的图像对象作为输入,同时你没有给Canvas设置和图片匹配的宽高,也会导致getImageData读取不到有效数据。
修复后的实现代码
// 从ffmpeg读取图片二进制数据 const data = ffmpeg.FS("readFile", "file_1.png"); // 1. 将Uint8Array转为Blob对象 const imgBlob = new Blob([data], { type: 'image/png' }); // 2. 生成Blob对应的临时URL const imgUrl = URL.createObjectURL(imgBlob); // 3. 加载图片对象 const img = new Image(); img.onload = () => { // 4. 初始化canvas尺寸和图片一致 const canvas = document.createElement("canvas"); canvas.width = img.width; canvas.height = img.height; const context = canvas.getContext("2d"); // 5. 绘制图片到canvas context.drawImage(img, 0, 0); // 6. 提取ImageData const myData = context.getImageData(0, 0, img.width, img.height); console.log("myData", myData); // 这里可以把myData传入TensorFlow的poseEstimation模块 // poseEstimation.estimatePoses(myData) // 释放临时URL避免内存泄漏 URL.revokeObjectURL(imgUrl); }; img.onerror = (err) => { console.error('图片加载失败,请检查二进制数据是否为有效png格式', err); URL.revokeObjectURL(imgUrl); }; // 触发图片加载 img.src = imgUrl;
异步同步化优化(可选)
如果你需要用async/await的写法避免回调嵌套,可以参考如下封装:
async function getImageDataFromUint8Array(uint8Data, mimeType = 'image/png') { const blob = new Blob([uint8Data], { type: mimeType }); const url = URL.createObjectURL(blob); try { const img = new Image(); await new Promise((resolve, reject) => { img.onload = resolve; img.onerror = reject; img.src = url; }); const canvas = document.createElement('canvas'); canvas.width = img.width; canvas.height = img.height; const ctx = canvas.getContext('2d'); ctx.drawImage(img, 0, 0); return ctx.getImageData(0, 0, img.width, img.height); } finally { URL.revokeObjectURL(url); } } // 调用示例 const myData = await getImageDataFromUint8Array(data); console.log("myData", myData);
无DOM环境兼容说明
如果你是在Node.js等没有原生DOM API的环境中运行,可以引入node-canvas库替代原生的canvas和Image对象,API用法和上述代码完全一致,不需要做过多修改。
内容的提问来源于stack exchange,提问作者Justin Lee
相关产品推荐
相关产品推荐

