There are times when you might want or need to know if an image has changed. For example, you might need to write a test that checks if your application draws something the same way every time. One way to check that would be to take a known good output and verify that the output of your application doesn't change when new features are added or the code is refactored.
One way to do that would be to use Pillow's ImageChops.difference
function.
You can't use the images you were using before because they are completely different, making this comparison pointless. Instead, you will use this image of a butterfly:
To make the comparison somewhat interesting, you can use this version of the butterfly that has a logo superimposed on it:
These images are in the GitHub repository for this book.
Here is the code definition for the difference()
function:
As you can see, it takes the two images and subtracts one from the other. Then it tries to apply an absolute value to the result. It's more complicated than that, but that's the general idea that the docstring describes. You can read more about it on Wikipedia.
Go ahead and create a new file named diff_image.py
with the following code:
Here you pass in the butterfly image as well as the watermarked butterfly image. You also tell your function, diff()
, where to save the output.
When you run this code, you will get the following output:
The black parts in the resulting image represent the pixels that are the same between the two images. The watermark is only present in one of them, so it is highlighted in the output. If the image has only a couple of pixels that are different, it can be hard to tell where the differences are. You may need to write some extra code to make it more obvious in that case.
Wrapping Up
Now you know the basics of comparing images and getting the difference using Python and Pillow. I have used this type of code in automated testing to verify that the software is drawing images the same way when new features are added or modified.
That was nice to see, thanks. I haven't explored the ImageChops module even though I use Image and ImageDraw a lot. I wish I'd realized it was that simple back when I did need to compare two images to see how they differed. I opened them with Image.open, pulled their data, and compared them pixel-by-pixel. Just tried that with ImageChops.difference, and it was (of course) a lot faster.