Я пытаюсь перенести один из моих проектов обработки (см. Страница 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];
}
}
}
Это функция, которую я использую для получения индекса в ImageData из значения x и y
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;
}
}
}
На самом деле нет способа показать проблему без изображения, поэтому вот изображение холста с изображением Годо Ло go. (Это растяжение, о котором я говорю). Изображение HTML5 canvas с Godot lo go bug (Вот ссылка на то, как выглядит исходное изображение). Godot lo go из Twitter
С точки зрения порядка выполнения функций, см. Ниже.
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);
};