Sean256
Sean256

Reputation: 3099

Why is html canvas botching this source image?

I'm toying around with making a super simple HTML Canvas crop tool. The first thing I tested was to see if the output image would be perceptually identical to the input image.

Using this image as a source, canvas fails to maintain the smooth gradients as you can see in the image comparison I posted here (still visible despite the imgur compression). You can also replicate it in any online photo editor such as https://pixlr.com.

Is there some way to fix this?

Left: Original, Right: After Canvas

Code snippet I am using:

const loadImageToCanvas = (file) => { // file is from input.files
    const img = new Image();
    img.onload = () => {
        const { width, height } = img;
        canvas.width = width;
        canvas.height = height;
        ctx.clearRect(0, 0, width, height);
        ctx.drawImage(img, 0, 0);
    }
    img.src = URL.createObjectURL(file);
};

Upvotes: 0

Views: 43

Answers (1)

hexwab
hexwab

Reputation: 1841

Two words: gamma correction. Your PNG file has a gAMA chunk of 1.0000. Web browsers are (correctly) using this information to adjust the displayed pixels for an output device having the standard sRGB gamma of 2.2. This behaviour is the same for both <canvas> and <img> elements.[1]

I don't know what viewer or conversion tool you are using to produce your imgur image, but it is either stripping or ignoring the gamma chunk.

If your image is in fact encoded with a gamma of 2.2 (and thus the gamma chunk is erroneous), you can remove the chunk with:

pngcrush -rem gAMA 1024.png 1024.nogamma.png


[1] The spec mandates this consistency. Are you really seeing different behaviour between your (correct, although using createObjectURL is unnecessary and a bad idea) code and an <img> tag?

Upvotes: 1

Related Questions