A pixel-level image comparison with PHP
Pixelmatch is a JavaScript library commonly used for visual regression testing in web development. It enables us to compare two images pixel by pixel and highlight the differences between them. This is valuable for detecting and addressing unintended visual changes in web interfaces. Pixelmatch helps ensure that web applications maintain a consistent visual appearance over time.
In PHP land, we can achieve image comparison using Imagick, a PHP extension. While Imagick is primarily designed for various image processing tasks, such as resizing, cropping, and applying filters, it can be leveraged to compare two images pixel by pixel.
When working with PHP extensions, I often encounter a set of challenges that can make the experience less enjoyable compared to using native PHP functions. One such challenge is the installation and configuration, which can be a barrier for those who may not have control over the server environment and may involve adjusting server-specific settings. Debugging can be challenging, and the available documentation can sometimes make it difficult to locate answers to questions.
Package solutions for extensions
Of course, there are already solutions for using a PHP package to manipulate images. You have Glide of Jonathan Reinink, and as far back as six years ago, the release of Image by our own Spatie team. Both packages make it more enjoyable to work with GD or Imagick. But one of the features it lacks, is the ability to perform a pixel-level image comparison.
As part of a big rewrite of spatie/image
, We made a new package, called spatie/pixelmatch-php, which uses the Pixelmatch javascript library under the hood.
Let's dive in the package API.
Match percentage between images
By comparing two image files, we can provide the percentage of mismatched pixels or the percentage of matched pixels.
use Spatie\Pixelmatch\Pixelmatch; $pixelmatch = Pixelmatch::new("path/to/file1.png", "path/to/file2.png"); $pixelmatch->mismatchedPixelPercentage(); // returns a float, for example 97.5$pixelmatch->matchedPixelPercentage(); // returns a float, for example 2.5
Amount of matching pixels
To get the amount of mismatched pixels, you can use the mismatchingPixels method.
use Spatie\Pixelmatch\Pixelmatch; $pixelmatch = Pixelmatch::new("path/to/file1.png", "path/to/file2.png"); $pixelmatch->matchedPixels(); // returns an int$pixelmatch->mismatchedPixels(); // returns an int
Or you can simple just see if they are identical with matches()
.
use Spatie\Pixelmatch\Pixelmatch; $pixelmatch = Pixelmatch::new("path/to/file1.png", "path/to/file2.png");$pixelmatch->matches(); // returns a boolean$pixelmatch->doesNotMatch(); // returns a boolean
In closing
Additionally, the library offers options such as the ability to ignore anti-aliasing and setting a custom threshold for pixel comparison. For more in-depth information, I recommend reading the docs.
If you are interested in how this package works under the hood, go check out the package code on Github!