我正在使用 html5 画布来渲染和图像,对图像进行一些基本的编辑,而不是尝试使用 getImageData(0 函数来读取像素并做一些工作。我注意到你,无论源图像的位深度如何是(8 位、16 位、24 位)getImageData() 方法允许返回 8 位(256 种颜色)。这是不可取的。我希望 getImageData(0 方法能吐出尽可能多的颜色。
我已经通读了文档,画布应该能够处理你扔给它的任何位深度(形象地)但我看不到任何地方可以将位深度设置得更高
我正在使用 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 缓冲区(它实际上在浏览器的加载时间,所以这不是画布本身做的事情)。
要从画布中读取数据,您有两个级别(或三个用于更高级的用途),包含各种信息的图像数据对象,包括对实际像素阵列视图的引用:
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);