Я работаю над репликой Paint, включающей манипуляции с ImageData
. На этой странице документации MDN статья говорит:
Из-за характера преобразования с потерями в предварительно умноженные значения альфа-цвета и обратно пиксели, которые только что были установлены с помощью putImageData(), могут быть возвращены в эквивалентный getImageData() как разные значения.
И приводит такой пример:
const canvas = document.createElement("canvas");
canvas.width = 1;
canvas.height = 1;
const context = canvas.getContext("2d");
const imgData = context.getImageData(0, 0, canvas.width, canvas.height);
const pixels = imgData.data;
pixels[0 + 0] = 1;
pixels[0 + 1] = 127;
pixels[0 + 2] = 255;
pixels[0 + 3] = 1;
console.log("before:", pixels);
context.putImageData(imgData, 0, 0);
const imgData2 = context.getImageData(0, 0, canvas.width, canvas.height);
const pixels2 = imgData2.data;
console.log("after:", pixels2);
Вывод в этом примере
before: Uint8ClampedArray(4) [ 1, 127, 255, 1 ]
after: Uint8ClampedArray(4) [ 255, 255, 255, 1 ]
Это противоречит здравому смыслу, так что я потратил 2 дня на поиск проблемы с моим кодом и не думал, что это действительно может работать так странно.
Итак, в статье не говорится о том, почему это происходит и как это обойти. Что я должен сделать, чтобы убедиться, что мой вызов putImageData
приведет к тем же самым данным, которые впоследствии будут возвращены getImageData
?
Прежде чем я увидел, как это работает таким образом, я всегда работал с полностью непрозрачными (каждый 4-й элемент равен 255) холстами. Это единственный способ гарантировать, что остальные данные не будут каким-то образом изменены при вызове putImageData
?