【问题标题】:How to draw pixels from an arraybuffer to the canvas very fast?如何快速将像素从数组缓冲区绘制到画布?
【发布时间】:2014-04-04 16:31:27
【问题描述】:

我有一个 asmjs 模块,它适用于名为“MEM”的ArrayBuffer。在每个循环中都会调用 repaint 函数。在第一个“大小”字节中是存储的像素颜色。我的代码有效,但运行缓慢。是否有可能以某种方式使其更快? arraybuffer 不能是 'siz' 长度,因为该模块适用于整个 ArrayBuffer。

var MEM = new ArrayBuffer(2*1024*1024);
var MEMU8 = new Uint8Array(MEM);
var imgData=ctx.createImageData(canvas.width,canvas.height);
var siz = (canvas.width*canvas.height*4)|0;

var rePaint = function() {
    var i=0;

    module.repaint();

    i=siz;
    while(i--) {
        imgData.data[i] = MEMU8[i];
    }

    ctx.putImageData(imgData, 0, 0);
    requestAnimationFrame(rePaint);
};

【问题讨论】:

  • 改用 Uint32Array 缓冲区?
  • 怎么样? ImageDada.data 是一个 UInt8ClampedArray,这就是我创建一个 Uint8Array 并复制每个元素的原因。

标签: javascript html canvas arraybuffer asm.js


【解决方案1】:

您可以通过使用类型化数组的 .set 方法获得性能:

不幸的是,IE 仍然使用 CanvasPixelArray 而不是新的 html 规范 (Uint8ClampedArray)。 IE 的 imageData.data 还没有 .set 方法。

但您仍然可以使用转换数组间接使用 .set:

// create a typed array to pipe data through
// (used to be able to do .set later)

buffer = new ArrayBuffer(imgData.data.length);

converterArray=new Uint8Array(buffer);

// In repaint

imgData.data = converterArray.set(MEMU8.subarray(0,siz));

【讨论】:

  • Uncaught RangeError: Source is too large
  • 我猜你的缓冲区大小可能大于siz。因此,您可以使用以下命令削减 MEMU8:imgData.data = converterArray.set(MEMU8.subarray(0,siz));
猜你喜欢
  • 1970-01-01
  • 2012-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-18
  • 1970-01-01
  • 2016-05-20
  • 1970-01-01
相关资源
最近更新 更多