Получить данные изображения uint8 без холста - PullRequest
0 голосов
/ 06 июня 2018

У меня есть сценарий использования, в котором я хочу передать данные image uint8 веб-работнику.Прямо сейчас я использую canvas для получения данных изображения uint8.Есть ли способ сделать это без холста.

Вот фрагмент кода, который я использую.

let img = new Image(),
        canvas = document.createElement('canvas'),
        context = canvas.getContext('2d');

img.crossOrigin = 'anonymous';
img.src = someImageUrl;

img.onload = () => {
            canvas.height = this.naturalHeight;
            canvas.width = this.naturalWidth;
            context.drawImage(img, 0, 0);
            const imgData = context.getImageData(0, 0, canvas.width, canvas.height);

            // post this imgData to the worker
            worker.postMessage(imageData);
        };

1 Ответ

0 голосов
/ 06 июня 2018

В ближайшем будущем вы сможете перейти с ImageBitmap , который вы передадите своему Рабочему, где вы будете обрабатывать его в OffscreenCanvas , который не являетсядействительно HTMLCanvas как таковой, но предлагает способ доступа к методам с одинаковым контекстом, даже внутри Worker.

На сегодняшний день только Chrome и Firefox начали разработку этого API, и они все еще скрыты под флагами в (" Experimental Web Platforms " для Chrome и " gfx.offscreencanvas.enabled " для Firefox).
И даже тогда,только Chrome реализовал 2DContext там, для Firefox вы должны были откатиться к контексту webgl, который я немного знаю, поэтому я позволю написать обходной путь, используя readPixels для кого-то другого.

Так что да, можно будет сделать это без HTMLCanvasElement, но сейчас ... Я думаю, вам лучше придерживаться холста.

if (!window.ImageBitmap || !window.OffscreenCanvas) {
  console.log('Your browser doesn\'t support ImageBitmap or OffscreenCanvas, we should fallback to a normal canvas');
} else {
  var img = new Image();
  img.crossOrigin = 'anonymous';
  img.onload = e => createImageBitmap(img).then(passToWorker);
  img.src = "https://upload.wikimedia.org/wikipedia/commons/5/55/John_William_Waterhouse_A_Mermaid.jpg";


  function passToWorker(bitmap) {
    var blob = new Blob([work.textContent], {
      type: 'application/javascript'
    });
    var worker = new Worker(URL.createObjectURL(blob));
    worker.postMessage(bitmap, [bitmap]);
    worker.onmessage = e => {
      if (e.data instanceof ImageData) {
        console.log('ImageData', e.data.data.length, e.data.data[0]);
      } else {
        console.log(e.data);
      }
    };
  }
}
<script id="work" type="worker-script">
onmessage = function(evt) {
  const bitmap = evt.data;
  try {
    const ctx = new OffscreenCanvas(bitmap.width, bitmap.height).getContext('2d');
    if(!ctx) fallbackToWebGL(bitmap);
    ctx.drawImage(bitmap, 0, 0);
    handleImageData(ctx.getImageData(0, 0, bitmap.width, bitmap.height));
  } catch (e) {
    console.log(e, e.name);
    // FF doesn't even return null...
    if (e.name === 'NS_ERROR_NOT_IMPLEMENTED') {
    	fallbackToWebGL(bitmap);
    }
    else postMessage('come back later');
  }
};

function handleImageData(data) {
  postMessage(data);
}

function fallbackToWebGL(bitmap) {
  postMessage('should fallback to webgl readPixels...');
}
</script>

О, и другой альтернативой было бы написать сам парсер любого формата, в котором находится исходное изображение, а затем самостоятельно извлечь каналы RGBA,но, честно говоря, использование Canvas не так уж и плохо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...