Canvas 将总是返回 24 位 数据 + 8 位 Alpha 通道 (RGBA)。每个分量值当然会有 8 位或 256 个值。这是每个规范。它永远不会返回 8 位索引图像数据,但是,如果您以某种方式遇到 8 位(索引)图像数据,那么您可能正在读取错误的数据或从对象/数组中读取数据。
来自specification:
图像数据。数据
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 开始,依此类推。
如果您出于某种原因需要将调色板减少为索引调色板,您必须自己提供算法。有很多从简单和坏到更复杂和准确的。但这不是你可以用画布开箱即用的东西。一些指针可以在 this answer 中找到,或者您可以使用库 such as this 从画布创建(动画)GIF。
还要注意,如果绘制到画布中的图像不满足跨域要求 (CORS),则画布将被“污染”(安全方面),getImageData() 将返回一个设置了值的数组为 0。