Javascript 可以直接在画布上绘制Uint8ClampedArray吗?

Javascript 可以直接在画布上绘制Uint8ClampedArray吗?,javascript,html,canvas,Javascript,Html,Canvas,在JavaScript中,可以使用uint8clampedaray直接操纵图像的像素。在将该图像渲染到画布之前,必须: 创建一个ImageData对象 使用ImageData.data.set将uint8clampedaray呈现为ImageData对象 使用context.putImageData将该ImageData对象绘制到画布上 因此,从图像具有uint8clampedaray,到在屏幕上实际看到图像,需要至少3次拷贝操作。对于大型图像,这可能非常有害。一种解决方案是缓存ImageDat

在JavaScript中,可以使用
uint8clampedaray
直接操纵图像的像素。在将该图像渲染到画布之前,必须:

  • 创建一个
    ImageData
    对象

  • 使用
    ImageData.data.set
    uint8clampedaray
    呈现为
    ImageData
    对象

  • 使用
    context.putImageData
    将该
    ImageData
    对象绘制到画布上

  • 因此,从图像具有
    uint8clampedaray
    ,到在屏幕上实际看到图像,需要至少3次拷贝操作。对于大型图像,这可能非常有害。一种解决方案是缓存ImageData对象,并将指针
    ImageData.data
    替换为您的
    Uint8ClampedArray
    ——但是
    ImageData.data
    是只读的!有什么方法可以更有效地执行此操作吗?

    根据,
    ImageData(数组、宽度、高度)
    构造函数接受第一个参数,即

    一个
    uint8clampedaray
    ,包含图像的基本像素表示

    快速测试验证此参数是否被引用(即未复制)用作
    ImageData
    data
    属性。此测试记录
    true

    var arr = new Uint8ClampedArray([0,0,0,0]);
    var idata = new ImageData(arr,1,1);
    console.log(idata.data === arr);
    

    因此,您可以通过在第一步中使用引用
    uint8clampedaray
    对象的
    data
    属性构造
    ImageData
    对象来消除第二步。顺便说一句,虽然这在大多数浏览器中都有效,但IE(IE9和我认为IE10)的愚蠢版本不使用
    uint8clampedarays
    。此外,imagedata构造函数会抛出“预期函数”错误。@Hans根据MDN和当前版本,它是合法的构造函数。您是否使用此答案的确切代码示例?什么浏览器?是否有进一步的改进?我在Uint8ClampedArray上大量使用直接像素值操作,如果我能将该数组交给画布进行渲染,那就太棒了。您可以创建一个
    ImageData
    并操作它的
    data
    属性(一个
    uint8clampedaray
    ),然后在每次更改像素时调用。要获得更高的性能,请使用边界框调用
    putImageData
    ,以仅重新绘制像素的子集(即,仅向画布提供框
    [(x,y)、(x+w,y+h)]中
    ImageData
    的像素)。(请参阅)如果您有更多问题,新的问题帖子将为您提供更好的答案(如果有,请给我一个链接!)。注意:虽然我的答案似乎是正确的(可能是唯一的)解决方法,但它可能不适用于IE10或更低版本(但我没有副本可供测试)。请参阅对我答案的评论。