使用getImageData()时,html5画布始终返回8位颜色



我正在使用一个html5画布来渲染和图像,对图像进行一些基本的编辑,而不是尝试使用getImageData(0函数来读取像素并做一些工作。我注意到,无论源图像的深度是多少(8位、16位、24位),getImageData)方法都允许返回8位(256色)。这是不可取的。我希望getImageData(0方法能吐出它收到的尽可能多的颜色。

我已经通读了文档,画布应该能够处理你向它抛出的任何比特深度(象征性地),但我看不到任何地方可以将比特深度设置得更高

Canvas将始终返回24位数据+一个8位alpha通道(RGBA)。当然,每个分量值将具有8位或256个值。这符合规范。然而,它永远不会返回8位索引的图像数据,因此,如果您以某种方式遇到8位(索引的)图像数据,那么您可能读取错误的数据或来自对象/数组的数据。

来自规范:

图像数据。数据

Returns the one-dimensional array containing the data in RGBA order,
as integers in the range 0 to 255.

只是为了涵盖相反的方面:如果你使用2-256色绘制一个8位索引调色板图像,如PNG-8或GIF,它们的索引调色板将始终转换为RGBA缓冲区(它实际上是在浏览器加载时转换为RGBA的,所以这不是画布自己做的事情)。

要从画布读取数据,您有两个级别(或三个级别用于更高级的使用),图像数据对象包含各种信息,包括对实际像素阵列视图的引用:

var imageData = context.getImageData(x, y, w, h);

从该对象中,我们获得像素的数据视图,默认情况下为Uint8ClampedArray视图:

var pixelData = imageData.data;

对于更高级的使用,我们可以从中获得原始字节缓冲区(如果您需要提供其他视图,即Uint32Array)

var rawBytes = pixelData.buffer;
var buffer32 = new Uint32Array(rawBytes);

但是,让我们坚持默认的8位钳制视图-要从中读取,您需要知道像素总是打包到RGBA中或作为32位值。因此,我们可以通过以下操作获得单个像素:

var r = pixelData[0];
var g = pixelData[1];
var b = pixelData[2];
var a = pixelData[3];

下一个像素将从索引4开始,依此类推

如果出于某种原因需要将调色板减少为索引调色板,则必须自己提供算法。有很多,从简单和糟糕到更复杂和准确的。但这不是你可以用画布开箱即用的东西。在这个答案中可以找到一些指针,或者你可以使用这样的库,它将从画布上创建(动画)GIF。

还要注意,如果绘制到画布中的图像不满足跨源要求(CORS),画布将被"污染"(安全方面),getImageData()将返回一个值设置为0的数组。

ImageData(由getImageData返回)属性data为您提供了一个数组,其中每个条目都是一个颜色通道,顺序为红色、绿色、蓝色和alpha,而不是实际颜色。例如

red=imgData.data[0];
green=imgData.data[1];
blue=imgData.data[2];
alpha=imgData.data[3];
colour = '#' + (red<16)?'0':'' + red.toString(16) +
(green<16)?'0':'' + green.toString(16) +
(blue<16)?'0':'' + blue.toString(16);

最新更新