我正在使用如下命令读取图像
gl.readPixels(0, 0, gl.width, gl.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);现在像素在一维数组中的长度为width*height*4。我不确定图像值是沿着哪个轴折叠的?直观地说,我希望它读取每一行,先向下移动Red列,然后是G、B、A(我称之为沿宽度折叠,然后是高度折叠,而不是RGBA)。
例如,如果我想访问图像底部倒数第二个像素中的红色值,我会使用:
<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>或者其他的命令。
发布于 2017-11-19 15:16:20
顺序是标准的GL顺序,即第一个像素对应于纹理、渲染器、画布中的0,0位置。
对于画布本身,0是左下角。对于纹理,没有底部的概念,有第一个像素(0,0),像素在(1,0),像素在(0,1),最后一个像素在(1,1)。
对于画布(因为它是唯一有固定方向的东西),第一行(底部)最右边的像素是data[(width - 1) * pixelSize]第三行最右边的像素是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。
https://stackoverflow.com/questions/47374367
复制相似问题