Как преобразовать необработанный байтовый массив изображения в изображение PNG, используя Javascript - PullRequest
0 голосов
/ 26 июня 2019

У меня есть необработанное изображение (в формате .raw без заголовка), которое я хочу преобразовать в формат PNG для отображения на холсте. Я попытался преобразовать необработанное изображение в RGBA, и оно оказалось успешным (путем манипулирования байтами и использования ImageData API на холсте). Теперь мне нужно конвертировать необработанное изображение в PNG.

Я пробовал,

  1. Извлечение изображения и создание массива буфера из ответа
  2. create UInt8Array изображения arraybuffer созданного.
  3. преобразовать его в base64:png содержимое

Может ли кто-нибудь помочь мне, пожалуйста?

Я пробовал несколько решений, найденных в интернете, но ни одно из них не работает для меня.

  1. Создание блоба и его использование, создание URL-адреса объекта и отображение на холсте - не работает
  2. Добавление заголовка 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, но я вижу пустой холст.

  3. Я также пытался добавить заголовок изображения 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;
      }

Я мог бы хотя бы увидеть изображение, отображаемое на холсте, но отличающееся от исходного.

1 Ответ

0 голосов
/ 26 июня 2019

Если у вас есть изображение в формате массива RGBA и вы можете напечатать его на холсте, вы можете просто использовать canvas.toDataURL(), чтобы получить строку PNG, такую ​​как "data:image/png;base64,ABCDEFG..."

Единственное ограничение, которое я знаю с canvas.toDataURL, заключается в том, что если вы загрузили изображение с другого сайта непосредственно на холст (т. Е. Через ctx.drawImage), он переведет холст в «поврежденное» состояние, чтобы вы не могли получить к нему доступ. изображение (это может применяться только при доступе к ImageData API). Однако, если вы удаленно загрузите необработанные данные изображения и используете API ImageData, я не думаю, что он будет запущен, поэтому должен работать следующий пример:

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

canvas.width = 200;
canvas.height = 150;

ctx.fillStyle = 'lightblue';
ctx.fillRect(0, 0, canvas.width, canvas.height)

ctx.fillStyle = 'blue';
ctx.fillText('Testing', canvas.width/2 - 20, canvas.height/2);

document.getElementById('dump').innerText = canvas.toDataURL();
#canvas {
  border: 1px solid black;
}
<canvas id='canvas'></canvas>
<p>As you can see the textarea has the PNG data url of the canvas</p>
<textarea id='dump'></textarea>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...