webgl readPixels以什么顺序将图像折叠为数组

时间:2017-11-19 06:45:54

标签: javascript html image-processing webgl

我正在使用

等命令读取图像
gl.readPixels(0, 0, gl.width, gl.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);

现在,像素在一维数组中的长度为width*height*4。我不确定图像值折叠在哪个轴上?直观地说,我希望它能读取每一行,首先向下移动红色,然后是G,B,A(我称之为沿宽度折叠,然后是高度,而不是RGBA)。

例如,如果我想在图像底部的右起第二个像素中访问RED值,我会使用:

<br>
pixels[width*height-2] (collapse along width, then height, then RGBA)<br>
pixels[width*height-1-height] (collapse along height, then width, then RGBA)<br>
pixels[width*height*4-8] (collapse along RGBA, then width, then height)<br>

或其他一些订单。

1 个答案:

答案 0 :(得分:0)

顺序是标准GL顺序,它是第一个像素对应于纹理,渲染缓冲区,画布中的0,0位置。

对于画布本身0,0是左下角。对于纹理,没有底部的概念,第一个像素(0,0),(1,0)处的像素,(0,1)处的像素和(1,1)处的最后一个像素。

对于画布(因为它是唯一具有设定方向的东西), 第一行(底部)中最右边的像素是data[(width - 1) * pixelSize] 第3行中最右边的像素为data[(width * 3 - 1) * pixelSize] 最后一行(顶部)中最右边的像素是data[(width * height - 1) * pixelSize]

一个简单的测试

const gl = document.querySelector("canvas").getContext("webgl");

gl.enable(gl.SCISSOR_TEST);
drawRectUsingScissor(0, 0, 1, 1, [ 1, 0, 0, 1]);
drawRectUsingScissor(1, 0, 1, 1, [ 0, 1, 0, 1]);
drawRectUsingScissor(0, 1, 1, 1, [ 0, 0, 1, 1]);
drawRectUsingScissor(1, 1, 1, 1, [ 1, .5, 0, 1]);

const width = 2;
const height = 2;
const pixelSize = 4;
const data = new Uint8Array(width * height * pixelSize);
gl.readPixels(0, 0, 2, 2, gl.RGBA, gl.UNSIGNED_BYTE, data);

log("raw: ", data);

for (let y = 0; y < height; ++y) {
 for (let x = 0; x < width; ++x) {
   const offset = (y * width + x) * pixelSize;
   log(x, ',', y, ':', data.slice(offset, offset + pixelSize)); 
 }
}

function drawRectUsingScissor(x, y, width, height, color) {
  gl.clearColor(...color);
  gl.scissor(x, y, width, height);
  gl.clear(gl.COLOR_BUFFER_BIT);
}

function log(...args) {
  const elem = document.createElement("pre");
  elem.textContent = [...args].join(' ');
  document.body.appendChild(elem);
}
canvas {
  width: 100px;
  height: 100px;
  image-rendering: pixelated;
}
pre { margin: 0 }
<canvas width="2" height="2"></canvas>

请注意,上述情况并非严格属实,因为您必须将gl.PACK_ALIGNMENT设置考虑在内,默认设置为4,但可以设置为1,2,4或8.对于RGBA / UNSIGNED_BYTE,您可以阅读我不得不担心PACK_ALIGNMENT