5

I create two images that should be identical, but their binaries are different:

$ convert -size 1x1 xc:white out1/w.png
$ sleep 1
$ convert -size 1x1 xc:white out2/w.png
$ diff out1/w.png out2/w.png 
Binary files out1/w.png and out2/w.png differ

Probably because of a timestamp in embedded metadata.

QUESTION: How to make ImageMagick create a binary that will always be the same?


Context

I have a big ImageMagick script that creates many images that are then saved to Git (because most developers don't have the environment necessary to run the script).

I often edit the script (ex:define a new image) and then run it to regenerate all images. But I don't want to have Git differences for images that have not changed.

Apparently some compression algorithms produce slightly different results on different architectures. Not a big problem since I always generate on the same machine. But even on the same machine, the files always all differ.

ImageMagick 6.8.9-9 Q16 x86_64 2015-08-06, on Ubuntu 2015.10

  • A self-contained example that people could test with would be useful. – Faheem Mitha Jan 14 '16 at 8:39
  • 1
    @FaheemMitha, there is a self-contained example, and Nicolas' reason for putting the binaries under source control seems reasonable to me. – Stephen Kitt Jan 14 '16 at 8:42
  • @FaheemMitha: The example does not require anything, it creates the images from scratch :-) – Nicolas Raoul Jan 14 '16 at 8:43
  • Related: stackoverflow.com/q/32251501 – Faheem Mitha Jan 14 '16 at 8:44
  • @NicolasRaoul Ok, noted. – Faheem Mitha Jan 14 '16 at 8:44
5

It should be possible to strip the timestamps, using -define png:exclude-chunks=date,time; but there's apparently a bug in the PNG encoder.

If you can stage your modifications, one possibility would be to use identify's signature to only replace an existing image if the pixel contents of the image change:

mkdir out
convert -size 1x1 xc:white out/w.png
if [ ! -f w.png ]; then
    mv out/w.png w.png
else
    if [ "$(identify -verbose w.png | awk '/ignature/ { print $2 }')" != "$(identify -verbose out/w.png | awk '/ignature/ { print $2 }')" ]; then
        mv out/w.png w.png
    else
        rm out/w.png
    fi
fi
  • Good find! Apparently someone has found the exact bug: studio.imagemagick.org/discourse-server/… so I guess the fix should be out soon? (I feel optimistic haha). The workaround is a good idea, I should try to make it easier to use for instance a bash convert_strip function. – Nicolas Raoul Jan 14 '16 at 9:09
  • Another option would be to strip the timestamps after image creation, e.g. with pngcrush -rem time (added bonus of further reducing size if possible). – Bob Jan 14 '16 at 13:24
2

You can use the -strip option:

$ convert -strip -size 1x1 xc:white out1/w.png
$ convert -strip -size 1x1 xc:white out2/w.png
$ md5sum out1/w.png out2/w.png 
<...same data...> *out1/w.png 
<...same data...> *out2/w.png 

EDIT:

It may have some bug in png-encoder, so if this method does not work, try one of these:

The +set option removes a particular information in generated file. Here, we remove the creation and modification dates.

$ convert +set date:create +set date:modify -size 1x1 xc:white out1/w.png
$ convert +set date:create +set date:modify -size 1x1 xc:white out2/w.png

or (second form, test to choose the one works for you)

$ convert +set date:create +set modify-date -size 1x1 xc:white out1/w.png
$ convert +set date:create +set create-date -size 1x1 xc:white out2/w.png

source: http://www.imagemagick.org/script/command-line-options.php

  • Adding -strip does not help here, strangely. I get different md5sums. Ubuntu 15.10. – Nicolas Raoul Jan 14 '16 at 8:42
  • What gives you the diff on hexdumped files? On my side (imagemagick 6.8.8-10) the first images differ on the creation and modification date (extDate fields) the images generated with -strip do not have these fields. – Mathieu Jan 14 '16 at 8:47
  • In light of the bug discussed in the other answer, you getting the same binary is quite a wonder, maybe your computer is fast and by chance you got the two same timestamps? – Nicolas Raoul Jan 14 '16 at 9:11
  • No, I analysed the generated files with hexdump and I see that the extDate fields where removed (and the files where smaller). A tips could be to remove dates with another method: +set date:create +set date:modify or +set create-date +set modify-date (I see these both examples that do not work for me) – Mathieu Jan 14 '16 at 9:44
  • This tip sounds interesting, could you please add to your answer the command line to generate the image using this tip? Thanks! – Nicolas Raoul Jan 14 '16 at 9:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.