Search code examples
javascripthtml5-canvasdata-uritodataurl

Why 2 identical images have different dataUrls?


I have 2 images both generated via javascript canvas. I want to check if both images are identical. For this I generated a set of images and saved them as png files. I then tried to compare the dataUrls of both, the previously generated image and the new generated image. But the dataUrls are different. Why is that so?

I used compare from imagemagick to doublecheck, that this images are really the same. The only difference is, that the first is available as file and the other is available via a canvas element.

I generated the dataUrls this way:

// first image: available as file:
<img src="image.png"> // var img = ...
var canvas1 = document.createElement('canvas')
canvas1.width = img.width
canvas1.height = img.height
canvas1.getContext('2d').drawImage(img,0,0)
canvas1.toDataURL()

// second image generated on canvas
canvas2.width = 500
canvas2.height = 500
canvas2.getContext('2d').rect(20,20,150,100);
canvas2.toDataURL()

Note, that this is only an issue for some pictures - not for all. The simple example shown above totally works.


Solution

  • I ended up creating two new image objects which I then used to draw them on another canvas from which I got the dataUrl - They finally matched then!

    var imageToCanvas = function (img) {
        var canvas = document.createElement('canvas')
        canvas.width = img.width
        canvas.height = img.height
        canvas.getContext('2d').drawImage(img, 0, 0)
        return canvas
    }
    
    let img1 = document.createElement('img')
    let img2 = document.createElement('img')
    
    let one, two
    
    img1.onload = function(){
        one = imageToCanvas(img1)
        cb()
    }
    
    img2.onload = function(){
        two = imageToCanvas(img2)
        cb()
    }
    
    img1.src = canvas.toDataURL() // my images generated with the same parameters like the reference images
    img2.src = images[i].src // my pregenerated reference images
    
    let cb = function(){
        if(!one || !two) return
    
        console.log(one.toDataURL(),two.toDataURL()) // the same
    
    }