我正在使用
等命令读取图像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>
或其他一些订单。
答案 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