Canvas.ToBlob не возвращает действительный PNG? - PullRequest
0 голосов
/ 13 апреля 2019

Я пытаюсь сохранить вывод canvas.toBlob в файл PNG, но вывод не похож на действительный PNG (хотя он близок). Первые 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 голосов
/ 13 апреля 2019

FileReader.readAsText без параметра кодирования будет читать ваш BLOB-объект с кодировкой UTF-8.

То есть байты 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-объект верен.
Вам нужно просто прочитать его как ArrayBuffer , а не как 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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...