3

我目前正在使用context.createImageData(width, height)HTML5 画布创建 RGBA 图像。但是我不需要操纵图像的 alpha 值,所以我创建的数组比它需要的要大得多。有没有办法使用类似的方法来创建 RGB 图像数据?

4

1 回答 1

6

你根本不能使用画布。

Canvas 将始终按照规范为您提供 RGBA 缓冲区(它产生 RGB 的唯一例外是当您用于toDataURL产生 JPEG 时)。

您可以简单地忽略 alpha 通道并将其保留为 255,或者创建一个自定义类型数组缓冲区,其中仅包含您操作的 RGB 值,然后将数据复制到画布的像素数组。

var myBuffer = new ArrayBuffer(3 * w * h);    /// calc buffer size in bytes
var pixels = new Uint8ClampedArray(myBuffer); /// view for buffer

Uint8ClampedArray与画布使用的缓冲区视图类型相同。

pixels然后在数据准备好时将值从复制到图像数据:

var imageData = ctx.createImageData(w, h);   /// create a canvas buffer (RGBA)
var data = imageData.data;                   /// view for the canvas buffer
var len = data.length;                       /// length of buffer
var i = 0;                                   /// cursor for RGBA buffer
var t = 0;                                   /// cursor for RGB buffer

for(; i < len; i += 4) {
    data[i]     = pixels[t];     /// copy RGB data to canvas from custom array
    data[i + 1] = pixels[t + 1];
    data[i + 2] = pixels[t + 2];
    data[i + 3] = 255;           /// remember this one with createImageBuffer

    t += 3;
}

ctx.putImageData(imageData, 0, 0); /// put data to canvas

(当然,两个缓冲区需要在宽度和高度上匹配)。

这种方法是否有益在很大程度上取决于您是否对图像进行了大量处理。如果不是,那么这只会使用更多内存,并且不会在性能上带来太多好处。

根据您将处理的方式和内容,还可以将 aUint32Array与您的自定义缓冲区一起使用(除了Uint8ClampedArray- 您可以在缓冲区上拥有任意数量的视图),这对于像素位移等很有用。

于 2013-11-09T05:23:12.233 回答