0

This code draws 1 x 1 dot by specified color on canvas.

function test(r, g, b, a) {
    const [width, height] = [1, 1]
    const rgba = [r, g, b, a]
    console.log(rgba)
    { // fillrect
        const canvas = Object.assign(document.createElement("canvas"), { width, height })
        const ctx = canvas.getContext("2d")
        ctx.globalAlpha = 1
        ctx.fillStyle = "#" + rgba.map(e => e.toString(16).padStart(2, "0")).join("")
        ctx.fillRect(0, 0, width, height)
        console.log(ctx.getImageData(0, 0, width, height).data)
    }
    { // putimagedata
        const canvas = Object.assign(document.createElement("canvas"), { width, height })
        const ctx = canvas.getContext("2d")
        ctx.globalAlpha = 1
        const imagedata = new ImageData(width, height)
        Object.assign(imagedata.data, rgba)
        ctx.putImageData(imagedata, 0, 0)
        console.log(ctx.getImageData(0, 0, width, height).data)
    }
}

I try some colors and results are following:

// Try Chrome
test(100, 100, 100, 100)
// [100, 100, 100, 100]
// [99, 99, 99, 100]
// [99, 99, 99, 100]

test(10, 100, 200, 50)
// [10, 100, 200, 50]
// [5, 97, 199, 50]
// [10, 102, 199, 50]

// Try Firefox
test(100, 100, 100, 100)
// [ 100, 100, 100, 100 ]
// [ 99, 99, 99, 100 ]
// [ 102, 102, 102, 100 ]

test(10, 100, 200, 50)
// [ 10, 100, 200, 50 ]
// [ 10, 102, 198, 50 ]
// [ 10, 102, 204, 50 ]

r, g, and b were changed. And, results differ between fillRect and putImageData. Furthermore, results differ between Chrome and Firefox.

Why? Is it a bug?

Finally I will create a no lossy image file which is not allowed color change. Are there alternatives?

blz
  • 837
  • 7
  • 20
  • 1
    Nope, can't really be called a bug, but a limitation. https://en.m.wikipedia.org/wiki/Canvas_fingerprinting The only workaround would be to get rid of the canvas to create your images and generate it entirely manually. – Kaiido Mar 31 '18 at 13:13
  • Thank you. I will search for methods other than Canvas. – blz Mar 31 '18 at 13:39

0 Answers0