> For the complete documentation index, see [llms.txt](https://docs.apryse.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.apryse.com/web/compare-files/pixels.md).

# Compare PDFs by using image pixel by pixel comparison

Efficiently compare PDFs with pixel-by-pixel image comparison. Utilize APIs to extract image data and overlay documents for detailed analysis. Enhance your document comparison process effortlessly. Th

{% hint style="info" %}
**Requirements**

*These packages are required to use these features in production. Trial keys have unlimited access to all features*

<a href="https://apryse.com/capabilities#Compare" class="button primary">Package: Compare</a>
{% endhint %}

If you would prefer to implement your own diffing algorithm, we provide APIs to retrieve image data from documents. You can use these images to compare the pixels between two documents by overlaying them and generating the output image. This is best for very custom uses. For most cases, we recommend using [PDF Overlay](/web/compare-files/pixels.md).

The setup is similar to the previous example, except this time we don't need to enable the full API. We can rewrite our `getDocument` function to look like this:

{% hint style="warning" %}
Please note that the following code snippets are very generic and assume both documents are the same size and have the same amount of pages. Please make sure you handle these cases yourself if you plan to implement this into your own project.

For most cases, we recommend using [PDF Overlay](/web/compare-files/pixels.md) - as seen in our [Image Overlay Demo](https://showcase.apryse.com/compare-files) or [full code sample](/web/get-started/samples/showcase-demo-compare-files.md).
{% endhint %}

{% tabs %}
{% tab title="JavaScript (SDK v8.0+)" %}
{% code lineNumbers="true" %}

```js
const [doc1, doc2] = await Promise.all([
  Core.createDocument('https://s3.amazonaws.com/pdftron/pdftron/example/test_doc_1.pdf'),
  Core.createDocument('https://s3.amazonaws.com/pdftron/pdftron/example/test_doc_2.pdf')
])
```

{% endcode %}

[Core.createDocument](https://sdk.apryse.com/api/web/Core.html#.createDocument__anchor)
{% endtab %}

{% tab title="JavaScript (SDK v6.0+)" %}
{% code lineNumbers="true" %}

```js
const [doc1, doc2] = await Promise.all([
  CoreControls.createDocument('https://s3.amazonaws.com/pdftron/pdftron/example/test_doc_1.pdf'),
  CoreControls.createDocument('https://s3.amazonaws.com/pdftron/pdftron/example/test_doc_2.pdf')
])
```

{% endcode %}

[CoreControls.createDocument](https://sdk.apryse.com/api/web/Core.html#.createDocument__anchor)
{% endtab %}
{% endtabs %}

Now we can write a function to get image data from these documents.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
const getImageData = (doc) => {
  return new Promise(resolve => {
    doc.loadCanvas({
      pageNumber: 1,
      drawComplete: (pageCanvas) => {
        const ctx = pageCanvas.getContext('2d');
        const imageData = ctx.getImageData(0, 0, pageCanvas.width, pageCanvas.height);
        resolve(imageData);
      }
    })
  })
}

// get image data for the first page of both our documents
const [imageData1, imageData2] = await Promise.all([
  getImageData(doc1, 0),
  getImageData(doc2, 0)
]);
```

{% endcode %}
{% endtab %}
{% endtabs %}

[loadCanvas](https://sdk.apryse.com/api/web/Core.Document.html#loadCanvas__anchor)

Now, we can loop over these pixels, and compare them however we wish.

{% tabs %}
{% tab title="JavaScript" %}
{% code lineNumbers="true" %}

```js
// Get the actual pixels from the ImageData object
const pixelData1 = imageData1.data;
const pixelData2 = imageData2.data;

const newImageData = new Uint8ClampedArray(pixelData1.length);

for(let i = 0; i < imageData1.length; i += 4) {
  // rgba values for each pixel in imageData1 (document 1)
  const r1 = pixelData1[i];
  const g1 = pixelData1[i + 1];
  const b1 = pixelData1[i + 2];
  const a1 = pixelData1[i + 3];

  // rgba values for each pixel in imageData2 (document 2)
  const r2 = pixelData2[i];
  const g2 = pixelData2[i + 1];
  const b2 = pixelData2[i + 2];
  const a2 = pixelData2[i + 3];

  // Implement your own diffing algorithm here
  newImageData[i] = someDiffFunction(r1, r2);
  newImageData[i+1] = someDiffFunction(g1, g2);
  newImageData[i+2] = someDiffFunction(b1, b2);
  newImageData[i+3] = someDiffFunction(a1, a2);
}

// Here you could create a new canvas with your diffed pixels,
// and open it with webviewer
const canvas = document.createElement('canvas');
canvas.width = imageData1.width;
canvas.height = imageData1.height;
canvas.getContext('2d').putImageData(new ImageData(newImageData, imageData1.width), 0 , 0);
canvas.toBlob((blob) => {
  readerControl.loadDocument(blob, { filename: 'image.png' });
})
```

{% endcode %}
{% endtab %}
{% endtabs %}

[ImageData](https://developer.mozilla.org/en-US/docs/Web/API/ImageData/ImageData/) [Canvas to blob](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob/) [readerControl.loadDocument](https://sdk.apryse.com/api/web/UI.html#.loadDocument)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.apryse.com/web/compare-files/pixels.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
