Edit: solution is (weirdly) to activate willReadFrequently: true on the canvas, Chromium & getImageData() will return consistent values, see answer below.
I'm currently running a program that pick a pixel from a canvas where an image is previously loaded using canvas.getImageData() , analyse the RGB values from the pixel then run calculations based on blue and red values.
I encountered a weird behavior only on Chrome/Chromium/Edge browsers : the first time and image is loaded, the value returned for a specific pixel is RGB(181,1,1), if i load the exact same image again in the canvas with canvas.drawImage() and pick the exact same pixel multiple times with canvas.getImageData() i now get RGB(181,1,2).
HTML:
<canvas id="canvas" width="500" height="500"></canvas>
JS:
var ctx = document.getElementById("canvas").getContext("2d", {alpha: false,});
const IMG = new Image();
IMG.src = "myImage.jpg"
ctx.drawImage(IMG, 0, 0, 500, 500);
console.log("first image draw : " + ctx.getImageData(66, 27, 1, 1).data);
ctx.drawImage(IMG, 0, 0, 500, 500);
console.log("Second image draw : " + ctx.getImageData(66, 27, 1, 1).data);
ctx.drawImage(IMG, 0, 0, 500, 500);
console.log("Third image draw : " + ctx.getImageData(66, 27, 1, 1).data);
ctx.drawImage(IMG, 0, 0, 500, 500);
console.log("Fourth image draw : " + ctx.getImageData(66, 27, 1, 1).data);
ctx.drawImage(IMG, 0, 0, 500, 500);
console.log("fifth image draw : " + ctx.getImageData(66, 27, 1, 1).data);
Result on Chrome :
"first image draw : 181,1,1,255"
"Second image draw : 181,1,1,255"
"Third image draw : 181,1,2,255"
"Fourth image draw : 181,1,2,255"
"fifth image draw : 181,1,2,255"
Result on Firefox :
"first image draw : 181,1,2,255"
"Second image draw : 181,1,2,255"
"Third image draw : 181,1,2,255"
"Fourth image draw : 181,1,2,255"
"fifth image draw : 181,1,2,255"
This behaviour only happen on chromium based browsers, on webkit/firefox i get RGB(181,1,2) no matter what.
I recreated this behaviour on codepen : open it on chrome/firefox and see the difference : https://codepen.io/sh4kman/pen/qBgaNbe
i tried :
- Disabling antialiasing (context.imageSmoothingEnabled= false)
- Clearing canvas (canvas.clearRect()) before/after every getImageData() call
I'm aware that different browser can have different render/rounding colors for images, but here i have different value on the same browser, always following the same pattern
I cannot give an actual answer to this but experimenting with the
willReadFrequentlyattribute of the canvas as mentioned in the warning of the console
I get different results on Chromium.
I forked the CodePen link and tried changing the values to
undefined(default)falseandtrue. All of them behave different from one another.undefined
The default behavior
false
Consistent behavior with the 3rd value being
1true
Consistent behavior with the 3rd value being
2Codepen link: https://codepen.io/Danny2006/pen/vYbXJWR