Compare PDF files using PHP and ImageMagick

DALL-E GeneratedLet's begin by creating two Imagick objects and load some PDFs.

<?php

declare(strict_types=1);

$controlDocument = new Imagick();
$compareDocument = new Imagick();

$controlDocument->readImage('control.pdf');
$compareDocument->readImage('compare.pdf');

If you try to run this code and get an exception about security policy: PHP Fatal error: Uncaught ImagickException: attempt to perform an operation not allowed by the security policy `PDF', you need to modify your ImageMagick policy to allow reading PDF files.

You can do that by opening /etc/ImageMagick-6/policy.xml and delete or comment out this line.

<policy domain="coder" rights="none" pattern="PDF" />

Now if you run your script it should work without any errors.

Next let's go and actually compare our documents. We are going to use the included method called compareImages. Add the following lines to our script.

$result = $controlDocument->compareImages($compareDocument, Imagick::METRIC_ABSOLUTEERRORMETRIC);

$result[0]->setImageFormat("png");
file_put_contents('diff.png', $result[0]);

This method returns an array containing our reconstructed image $result[0] and number of pixels that are different $result[1] (in our case since we are using AE as our metric).

We can calculate the difference in percentages using some simple math.

$diffPercentage = $result[1] * 100 / ($controlDocument->getImageWidth() * $controlDocument->getImageHeight());

echo number_format($diffPercentage, 4) . "%";

Here's how it looks on my example documents.

And here's the result image and difference.

Document is 1.7903% different.

Now you can easily adapt this code into your test suit.

Additional information

// Add this before loading the image
// Pixels may be different by up to 5% before being considered different
$controlDocument->setOption('fuzz', '5%');
  • You can control the image resolution.

// Add this before loading the image
$controlDocument->setResolution(100, 100);
$compareDocument->setResolution(100, 100);

Find me on