Update from 2017: I completely forgot about this answer, but the reason is related to the preliminary multiplication of data when receiving / setting. Since the numbers in the bitmap are always integers, there will be rounding errors, since the natural result of preliminary multiplication often leads to non-integer numbers.
Unfortunately, there is no convenient way to fix this.
Just to clarify the gamma below: Gamma (through the gamma setting or ICC profile) will affect images directly, but for figures drawn directly on the canvas, this should not be a problem per se, since only the gamma of the display from above is adjusted, not the data itself.
Old answer:
What you experience is likely the result of a partial implementation of the color and gamma correction sections in the canvas standard.
The reason for the different color values, at least when it comes to images containing ICC profiles, is due to the built-in color and gamma correction in browsers:
4.8.11.1 Color spaces and color correction
The canvas APIs need to perform color correction only at two points: when rendering images with their own gamma correction and color space information to the canvas, in order to convert the image to the color space used by the canvas (for example, using the 2D Context drawImage () method with an object HTMLImageElement) and when rendering the actual canvas, the bitmap to the output device.
Source: w3.org
However, it is also indicated in section 4.8.11.1:
Note. Thus, in a 2D context, the colors used to draw shapes on the canvas will exactly match the colors obtained using the getImageData () method.
Since the state this is written to is work in progress , I assume that browsers have a βlazyβ implementation of color and gamma correction, which currently also affects the color information on the figure, or all data from the canvas is adjusted for display as the last paragraph in the first quote. This may not change until the standard is final.