无画布获取图像uint8数据

时间:2018-06-06 08:48:41

标签: javascript image html5-canvas

我有一个用例,我希望将图像uint8数据传递给Web worker。 现在我正在使用画布来获取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 :(得分:1)

在不久的将来,您应该能够从ImageBitmap转移到您的工作人员,在那里您可以在OffscreenCanvas中处理它,这不是真正的HTMLCanvas se,但提供了一种访问相同上下文的方法。方法,甚至在工人内部。

截至今天,只有Chrome和Firefox已经开始开发此API,它们仍然隐藏在两个标志下(" 实验性网络平台 "适用于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>
&#13;
&#13;
&#13;

哦,另一种选择是自己编写一个原始图像格式的解析器,然后自己提取RGBA通道,但老实说,使用Canvas并不是那么糟糕。