Canvas.ToBlob没有返回有效的PNG?

时间:2019-04-13 14:15:57

标签: javascript html5 canvas

我正在尝试将canvas.toBlob输出保存到PNG文件中,但是输出看起来好像不是有效的PNG(尽管已关闭)。第1个4个字节应为(十六进制)“ 89 50 4e 47”。相反,我得到的是“ ff fd 50 4e 47”,即不是“ 89”,而是“ ff fd”。当我尝试打开PNG文件时,Paint之类的应用程序说它无效。下面的示例显示了输出到控制台的格式,但未保存文件。

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.fillRect(25, 25, 100, 100);     

canvas.toBlob(function(blob) {
    const reader = new FileReader();
    reader.addEventListener('loadend', (e) => {
        var result = e.srcElement.result;
        var hex = StrToHex(result);
        console.log(`result=${result}`);
        console.log(`hex=${hex}`);
    });
    reader.readAsText(blob);
});

1 个答案:

答案 0 :(得分:0)

没有编码参数的

added support将以UTF-8编码读取您的Blob。

也就是说,字节89 50 4e 47变为字符串�PNG。您在这里所做的是从此字符串获取十六进制,这与原始字节值不同:

// build a Blob from this hex string
const originalStrHex = '89 50 4e 47';
const hexAsUint8 = originalStrHex
  .split(' ')
  .map((v) => parseInt(v, 16));
const bytes= Uint8Array.from(hexAsUint8);
const reader = new FileReader();
reader.readAsText(new Blob([bytes]));
reader.onload = e => {
  const res = reader.result;
  console.log(res);
  const fromUTF8 = new TextEncoder().encode(res);
  const strHex = [...fromUTF8]
    .map(v => v.toString(16).padStart(2, "0"))
    .join(' ');
  // if that was correct, we should have had the same as originalStrHex
  console.log(strHex);
};

所以,可能是您的Blob是正确的。
您想要的只是FileReader.readAsText,而不是作为UTF-8字符串:

document.createElement('canvas').toBlob(handleBlob);

function handleBlob(fullblob) {
  const blob = fullblob.slice(0, 4);
  const reader = new FileReader();
  reader.onload = e => {
    const view = new Uint8Array(reader.result);
    const strHex = [...view].map(v => v.toString(16).padStart(2, "0")).join(' ');
    console.log(strHex);
  };
  reader.readAsArrayBuffer(blob);
}