Bongo
Bongo

Reputation: 3153

Javascript canvas.getImageData IE vs Chrome

I have a canvas object from which i want to get the color of a position with canvas.getImageData. When i paint a gradient on it and try to get the color from point (0,0) chrome behaves as expected and returns the color value 255,255,255 whereas IE returns 254,253,253.

I have here a plunker which shows what i mean :

http://plnkr.co/edit/BWSn2J2N2A6poaH4WR6a?p=preview

You can just execute this in IE and in Chrome and you'll see the difference. I use the IE v11 and the Chrome v40.

Maybe the error is during my creation of the canvas.

var RepaintGradient = function(gradient)
{           
    _gradientContext.fillStyle = 'rgb(255,0,0)';
    _gradientContext.fillRect(0,0,width,height);

    var gradientWTT = _gradientContext.createLinearGradient(0, 0, width, 0);
    gradientWTT.addColorStop(0, "white");
    gradientWTT.addColorStop(1, gradient);
    _gradientContext.fillStyle = gradientWTT;
    _gradientContext.fillRect(0, 0, width, height);

    var gradientBTT = _gradientContext.createLinearGradient(0, width, 0, 0);
    gradientBTT.addColorStop(0, "black");
    gradientBTT.addColorStop(1, "transparent");
    _gradientContext.fillStyle = gradientBTT;
    _gradientContext.fillRect(0, 0, width, height);
    var color = _gradientContext.getImageData(0, 0, 1, 1).data;
    alert(color[0]+' '+color[1]+' '+color[2]);
};

Is this a normal behavior and IE and Chrome have this difference or is it something that i missed during the creation of the canvas ?

Upvotes: 1

Views: 627

Answers (2)

user1693593
user1693593

Reputation:

This is due to rounding errors during blending and composition when sub-pixeling is used - different browsers gain different result based on their approach (IE and FireFox gives the same result, webkit browsers a different result).

It's not much we can do with the inner working, but we can adjust for sub-pixeling so it won't happen by simply translating the canvas half pixel.

Add this line to the top of the gradient function:

  _gradientContext.setTransform(1,0,0,1, 0.5,0.5); // offset 0.5 pixel

and it should work

The reason being that pixels are initially rendered from the pixel's center, meaning 0.5 of the pixel is interpolated both ways. Translating 0.5 pixel will match the center to the pixel grid.

Update (from comments):

Another approach using coordinates to calculate color value (HSL) instead of picking a pixel (this approach will also allow you to set a point in the picker based on input values):

Upvotes: 1

markE
markE

Reputation: 105015

It's normal...

Different browsers are allowed to impliment slightly different renderings of canvas gradients.

Even one image will be rendered slightly differently on each browser.

Upvotes: 1

Related Questions