-
Notifications
You must be signed in to change notification settings - Fork 170
Description
I am trying to adjust the contrast and brightness of an image by editing the pixel data directly.
My idea was to get the corresponding ImageData by getImageData and then modify the data of the ImageData and then pass the ImageData into putImageData. But I found that although the data value of the ImageData has changed, the putImageData method does not seem to draw the modified image.
If I initialise the modified values to a new ImageData class, and pass the new one to the putImageData, the image can be drawn, but there is a problem with flickering when it changes continuously. My code is posted below:
const handleDraw = (level) => {
setLevel(level)
let tmp = imageData.data //imageData is a state set in the handleCanvas
for (let i=0; i<tmp.length; i+=4) {
tmp[i] = tmp[i] + level > 255 ? 255 : tmp[i] + level < 0 ? 0 : tmp[i] + level
tmp[i+1] = tmp[i+1] + level > 255 ? 255 : tmp[i+1] + level < 0 ? 0 : tmp[i+1] + level
tmp[i+2] = tmp[i+2] + level > 255 ? 255 : tmp[i+2] + level < 0 ? 0 : tmp[i+2] + level
}
globalCanvas.getContext('2d').putImageData(imageData, 0, 0); //globalCanvas is a state set in the handleCanvas.
}
BTW I found that the return value structure of the ImageData constructor and the getImageData function is a bit different, despite they all return ImageData class. Please see the code and output below:
let tmp = new ImageData(canvas, new Array(512*512*4).fill(255), 512, 512)
console.log('Constructor: ', Object.keys(tmp));
const ctx = canvas.getContext('2d');
ctx.putImageData(tmp, 0, 0);
ctx.getImageData(0, 0, 512, 512).then(res => {
setImageData(res)
console.log('getImageData', Object.keys(res));
})
and the output:
Constructor: Array [
"postMessage",
"addMessageListener",
"canvas",
"@@WEBVIEW_TARGET",
]
getImageData Array [
"postMessage",
"addMessageListener",
"canvas",
"data",
"@@WEBVIEW_TARGET",
"width",
"height",
]