我正在尝试将我的一个处理项目(请参阅项目的 Github 页面)移植到 vanilla Javascript,但我遇到了将数据从一个 ImageData 对象“移植”到另一个 ImageData 对象的问题。我可以用一个颜色的矩形填充画布的一个区域就好了,但由于某种原因,同样不适用于图像。
这是我用来将 ImageData 的一个区域放入另一个图像数据区域的代码。
image(ix, iy, iw, ih, i) {
let xMin = ix;
let xMax = ix + iw;
let yMin = iy;
let yMax = iy + ih;
if (xMin < 0) xMin = 0;
if (xMax > this.w) xMax = this.w;
if (yMin < 0) yMin = 0;
if (yMax > this.h) yMax = this.h;
let data = this.buffer.data;
let im_data = i.buffer.data;
for (let x = xMin; x < xMax; x++) {
for (let y = yMin; y < yMax; y++) {
let i_x_off = x - ix;
let i_y_off = y - iy;
let ind = this.index(x, y);
let i_ind = this.index(i_x_off, i_y_off);
data[ind + 0] = im_data[i_ind + 0];
data[ind + 1] = im_data[i_ind + 1];
data[ind + 2] = im_data[i_ind + 2];
data[ind + 3] = im_data[i_ind + 3];
}
}
}
这是我用来从 x 和 y 值获取 ImageData 索引的函数
index(x, y) {
return y * (this.w * 4) + (x * 4);
}
这是我用来将矩形放到画布上的函数。注意它与image()
函数的相似程度
rect(rx, ry, rw, rh, c) {
let xMin = rx;
let xMax = rx + rw;
let yMin = ry;
let yMax = ry + rh;
if (xMin < 0) xMin = 0;
if (xMax > this.w) xMax = this.w;
if (yMin < 0) yMin = 0;
if (yMax > this.h) yMax = this.w;
let data = this.buffer.data;
for (let x = xMin; x < xMax; x++) {
for (let y = yMin; y < yMax; y++) {
let i = this.index(x, y);
data[i + 0] = c.r;
data[i + 1] = c.b;
data[i + 2] = c.g;
data[i + 3] = c.a;
}
}
}
没有图像就无法真正显示问题,因此这里是带有 Godot 徽标图像的画布图像。(这就是我所说的拉伸)。 带有 Godot 徽标错误的 HTML5 画布图像 (这里是源图像外观的参考)。来自 Twitter 的 Godot 徽标
就函数执行的顺序而言,请参见下文。
const main = () => {
raw.flush(); // Setting all the "pixels" to RGBA 0, 0, 0, 0
raw.rect(10, 10, im.w, im.h, color());
raw.image(10, 10, im.w, im.h, im);
GLOBALCANVASCONTEXT.putImageData(raw.buffer, 0, 0); // The buffer is just another name for the result of ctx.createImageData(w, h)
window.requestAnimationFrame(main);
};