【发布时间】:2019-11-08 03:47:09
【问题描述】:
我有一个原始图像(.raw 格式,没有任何图像标题),我想将其转换为 PNG 格式以显示在画布上。我尝试将原始图像转换为 RGBA 并且它成功(通过操作字节并在画布中使用 ImageData API)。现在我需要将原始图像转换为 PNG。
我试过了,
- 从响应中获取图像并创建数组缓冲区
- 创建图像
arraybuffer的UInt8Array。 - 将其转换为
base64:png内容
谁能帮帮我?
我尝试了在互联网上找到的多种解决方案,但没有一个适合我。
- 创建一个 blob 并使用它构造一个对象 URL 并在画布上显示 - 无效
-
将 PNG 图像标题添加到字节数组并显示在画布上。
fetch(image.src).then(resp => { // load from original source return resp.arrayBuffer(); //return resp.blob(); // obtain a blob }).then(arrayBuffer => { let int8array = new Uint8Array(arrayBuffer); let base64content = this.arrayBufferToBase64(int8array.buffer); let newImg = document.createElement('img'); newImg.src = 'data:image/png;base64,' + base64content; this.context.drawImage(newImg, 0, 0); }); arrayBufferToBase64( buffer ) { let binary = ''; let bytes = new Uint8Array( buffer ); var len = bytes.byteLength; for (let i = 0; i < len; i++) { binary += String.fromCharCode( bytes[ i ] ); } return window.btoa( binary ); }我希望结果是在画布上绘制 png 图像,但我看到的是空画布。
我还尝试将PNG图像标题直接添加到图像的
bytearray内容
fetch(image.src).then(resp => {
return resp.arrayBuffer();
}).then(arrayBuffer => {
let int8array = new Uint8Array(arrayBuffer);
let signature = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]);
let newArray = new Uint8Array(int8array.length + signature.length);
newArray.set(signature);
newArray.set(int8array, signature.length);
const imgData = this.uint8ToImageData(newArray, 500, 500);
this.context.putImageData(imgData, 0, 0);
});
uint8ToImageData(uint8, width, height) {
let iData = this.context.createImageData(width, height);
for (let i = 0; i < uint8.length; i++) {
iData.data[i] = uint8[i];
}
return iData;
}
我至少可以看到画布上显示的图像,但与原始图像不同。
【问题讨论】:
-
图片与原图有何不同?
-
像素好像有不同的值,所以外观看起来有不同的颜色,但有相同的原始图像痕迹。
-
好的,但是如果您使用我发布的代码,是否会为您提供 PNG 数据 url,即使它不起作用?如果是这样,问题只是调试代码的问题。如果您编辑以包含原始版本和画布版本的屏幕截图,这可能会更容易。
-
是的,我可以看到带有您的代码的 PNG 数据 URL。关于截图,我不能在这里发布,因为它是我公司内部的。
-
好的,很公平。不过,在#3 的代码中,我发现在使用
putImageData之前将 PNG 签名添加到原始图像数据中很奇怪,因为您实际上在做的是绘制 2 个像素(4 个字节/像素)的PNG 签名到画布上,然后未对齐图像的其余部分。我将从删除签名开始,因为您不是在写入实际的 PNG 文件,而是在画布上。
标签: javascript angular html5-canvas