Question

After setting a certain colour as the fillStyle of the canvas and drawing a rectangle with fillRect, the colour of the rectangle sometimes differs a bit from the one provided (the getImageData returns different values - usually one of them is lower by 1). It seems to happen only when using rgba colours (and not with rgb) but I actually do need to use the alpha channel.

I've made a simple test suite on js fiddle for anyone who would like to look into this issue: http://jsfiddle.net/LaPdP/1/

Any ideas on why is this happening and if there is any way to fix that? If it at least happened always on the same value then I'd just bypass it by increasing it by 1, but it seems quite random to me.

Was it helpful?

Solution

Update from 2017: I forgot completely about this answer, but the cause is related to pre-multiplying the data, when getting/setting. As the numbers in a bitmap is always integer there will be rounding errors as the natural result of pre-multiplying often result in non-integer numbers.

There is unfortunately no convenient way to fix this.

Just to clarify about gamma below: Gamma (via a gamma setting or an ICC profile) will affect images directly, but for shapes drawn directly to the canvas this should not be a problem per-se as only the display gamma is adjusted on top, not the data itself.

Old answer:

What you are experiencing is probably a result of only a partial implementation of the color and gamma correction section in the canvas standard.

The reason for various color values, at least when it comes to images containing ICC profiles, is due to the built-in color and gamma correction in the browsers:

4.8.11.1 Color spaces and color correction

The canvas APIs must perform color correction at only two points: when rendering images with their own gamma correction and color space information onto the canvas, to convert the image to the color space used by the canvas (e.g. using the 2D Context's drawImage() method with an HTMLImageElement object), and when rendering the actual canvas bitmap to the output device.

Source: w3.org

However, it also states in section 4.8.11.1:

Note: Thus, in the 2D context, colors used to draw shapes onto the canvas will exactly match colors obtained through the getImageData() method.

As the status as this is written is a work in progress my guess is that the browsers has a "lazy" implementation of color and gamma correction which currently also affects shapes - or - all color information from the canvas is corrected to display profile as the latter point in first quote. This will perhaps not change until the standard becomes final.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top