Mark's answer is spot-on. However, he forgot to mention that compare
can also return a 'delta image', which will paint any pixel with differences as red, while identical pixels will be white.
# Create a PNG and a JPEG from the builtin 'wizard:' image:
convert wizard: wizard.png
convert wizard: wizard.jpg
Now compare the two:
compare wizard.png wizard.jpg delta.png
This is the 'delta.png':

Lots of differences between PNG and JPEG! Ok, this is explained by the fact that JPEG is a lossy image format...
As you can see, the 'delta.png' has a pale background. If you do not want this background, but only red/white pixels, modify the compare
command:
compare wizard.png wizard.jpg -compose src delta.png
Also, you may want to ignore such differences which are below a certain threshold. Here the -fuzz N%
parameter comes in handy.
You want blue pixels instead of red? And yellow ones instead of white? Here you go:
compare \
-highlight-color blue \
-lowlight-color yellow \
-fuzz 3% \
wizard.png \
wizard.jpg \
delta2.png

You want a textual description of all pixels which are different with their respective coordinates? Here the special output format *.txt
may be good.
Try this:
compare \
-fuzz 6% \
wizard.png \
wizard.jpg \
-compose src \
delta3.txt
The 'delta3.txt' file will be quite large, because it contains one line per pixel in this format:
# ImageMagick pixel enumeration: 480,640,255,srgba
0,0: (255,255,255,0.8) #FFFFFFCC srgba(255,255,255,0.8)
1,0: (255,255,255,0.8) #FFFFFFCC srgba(255,255,255,0.8)
2,0: (255,255,255,0.8) #FFFFFFCC srgba(255,255,255,0.8)
[....]
77,80: (241,0,30,0.8) #F1001ECC srgba(241,0,30,0.8)
[....]
The first column gives the (row,column)
pair of the respective pixel (counting is zero-based, the topmost, leftmost pixel has the address (0,0)
.
The next three columns return the respective pixel color, in 3 different common notation formats.
BTW, ImageMagick can convert the delta3.txt
file back to a real image without any problem:
convert delta3.txt delta3.png
So to get all the pixels which are different (red) into a text file, you could do this:
compare \
-fuzz 6% \
wizard.png \
wizard.jpg \
-compose src \
txt:- \
| grep -v '#FFFFFFCC'
To count the number of different pixels:
compare \
-fuzz 6% \
wizard.png \
wizard.jpg \
-compose src \
txt:- \
| grep -v '#FFFFFFCC' \
| wc -l
With -fuzz 6%
I have 2269
different pixels. With -fuzz 0%
I get 122474
different pixels. (Total number of pixels in these images was 307200
.)