Screenery / Tools / Compare screenshots
Compare two screenshots
Add a before and an after image to see which pixels changed. You get a highlighted diff, a side-by-side view and a slider, with the changed-pixel count and the regions that changed.
Your images never leave this device. The page decodes them in your browser, compares them in JavaScript, and loads no third-party scripts.
Paste with Ctrl+V or ⌘V. A pasted image goes into the box you last focused, or the first empty one. Drop two files at once to fill both boxes.
0 counts any difference. 0.1 is the default.
changed anti-aliasing, ignored region outline. Everything else is the before image, darkened.
Download the diff as PNGHow a pixel diff works
The tool reads both images into pixel arrays and compares them one pixel at a time, at the same position. For each pair it converts the colours to YIQ, which splits a colour into brightness and two colour axes, and measures the distance between them. Brightness carries the most weight, because eyes notice it most. When that distance is over the threshold, the tool counts the pixel as changed and draws it red.
The method comes from the open-source pixelmatch library. Screenery's visual-diff gate uses the same colour distance and the same default threshold. For the same two PNGs, the changed-pixel count here should match the gate's. The tool blends translucent pixels over white first, so they compare as they would look on a page.
Then the tool groups the changed pixels into regions. It splits the image into 16-pixel squares. Changed squares that touch form one region, with one box around it. A region count tells you more than a pixel count. A button that moved 6 pixels can be thousands of red pixels, but it is one region.
Any image your browser can decode works: PNG, JPEG, WebP, the first frame of a GIF, and AVIF in most browsers. Each image can be up to 40 million pixels.
Choosing a threshold
The threshold runs from 0 to 1. At 0, any difference at all counts, including a change of one shade of grey. The default of 0.1 ignores tiny colour shifts that nobody would see, and still catches a changed colour, moved text or a missing icon. A higher threshold ignores bigger colour differences.
- Two PNG screenshots from the same browser and machine: keep 0.1.
- JPEG screenshots, or resized images: try 0.2 to 0.3. Compression adds noise to every edge.
- Use 0 to check that two exports are identical.
Anti-aliasing
Browsers draw text and curved edges with in-between shades so they look smooth. Those shades depend on the font renderer, the GPU and the operating system, so the same page captured on two machines differs along every edge.
With Ignore anti-aliasing on, the tool checks each changed pixel's neighbours. If the pixel sits between a darker and a brighter neighbour, next to an area of flat colour in both images, the tool treats it as an edge pixel, draws it yellow and does not count it. The check comes from pixelmatch.
It is off by default, to match Screenery's gate, which counts every anti-aliased pixel as a change. Turn it on when you compare screenshots taken on different machines. For the gate, capture the baseline on the same kind of runner as CI, so both sides render the same way.
Images of different sizes
When the two images differ in size, the tool compares the area they share, starting from the top-left corner, and reports how many pixels it left out. It does not scale or align either image.
A screenshot that got taller usually means something near the top grew and pushed the rest of the page down. Everything below that point then shows as changed. Fix the first change and compare again. By default, Screenery's gate fails a screenshot whose width or height changed.
Do this on every pull request
This page compares two files once. Screenery runs the same comparison in CI, on every screenshot your tests write. You commit a baseline folder of approved screenshots and point the screenery/push@v1 Action at it:
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
# … your Playwright step writes test-results/ …
- uses: screenery/push@v1
with:
project: acme/dashboard
path: test-results
diff-baseline: ./screenery-baseline
The Action compares each screenshot with the file of the same name in the baseline before it publishes anything. If one changed, the job fails and the Action pushes nothing. If none did, the push publishes as usual. By default one changed pixel fails the job. You can grade changes as minor, moderate or major and choose which grade fails. To run the same check on your own machine, with no credential and no network:
npx screenery diff ./test-results --baseline ./screenery-baseline
Using Playwright already? See Playwright screenshots. The console can also compare two versions of a published screenshot. See Comparing versions in the console.