ODIFF
The fastest in the world pixel-by-pixel image difference tool.
Why Odiff?
ODiff is a blazing fast native image comparison tool. Check benchmarks for the results, but it compares the visual difference between 2 images in milliseconds. It was originally designed to handle the "big" images. Thanks to Ocaml and its speedy and predictable compiler we can significantly speed up your CI pipeline.
Demo
base | comparison | diff |
---|---|---|
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Features
- ✅ .png, .jpg, .jpeg, .bmp – Files supported.
- ✅ Cross-format comparison - Yes .jpg vs .png comparison is real.
- ✅ Supports comparison of images with different layouts
- ✅ Using YIQ NTSC transmission algorithm to determine visual difference
- ✅ Zero dependencies for unix. Requires libpng only for windows
Coming in the nearest future:
- ⏹ Ignoring regions
- ⏹ Anti-aliasing support
- ⏹ Remote images compare
Usage
Basic comparison
Run the simple comparison. Image paths can be one of supported formats, diff output can only be .png
.
odiff <IMG1 path> <IMG2 path> <DIFF output path>
Node.js
We also provides direct node.js binding for the odiff
. Run the odiff
from nodejs:
const { compare } = require("odiff-bin");
const { match, reason } = await compare(
"path/to/first/image.png",
"path/to/second/image.png",
"path/to/diff.png"
);
Api
Here is an api reference:
CLI
The best way to get up-to-date cli interface is just to type the
odiff --help
Node.js
NodeJS Api is pretty tiny as well. Here is a typescript interface we have:
type ODiffOptions = {
/** Output full diff image. */
diffImage: boolean;
/** Do not compare images and produce output if images layout is different. */
failOnLayoutDiff: boolean;
/** Color difference threshold (from 0 to 1). Less more precise. */
threshold: number;
};
declare function compare(
basePath: string,
comparePath: string,
diffPath: string,
options?: ODiffOptions
): Promise<
{ match: true } | { match: false; reason: "layout-diff" | "pixel-diff" }
>;
Compare option will return { match: true }
if images are identical. Otherwise return { match: false, reason: "*" }
with a reason why images were different.
Make sure that diff output file will be created only if images have pixel difference we can see 👀
Installation
⛔️ for windows users ⛔️ It is required to install http://www.libpng.org/pub/png/libpng.html manually. But there is a great chance that it was already installed by some other program.
Cross-platform
The recommended and cross-platform way to install this lib is npm and node.js. Make sure that this package is compiled directly to the platform binary executable, so the npm package contains all binaries and post-install
script will automatically link the right one for the current platform.
Important: package name is odiff-bin. But the binary itself is odiff
npm install odiff-bin
Then give it a try 👀
odiff --help
MacOS
⛔️ Doesn't work. Waiting for brew approve ⛔️
brew install odiff
Alpine Linux
apk add odiff
From binaries
Download the binaries for your platform from release page.
Benchmarks
Run the benchmarks by yourself. Instructions of how to run the benchmark is here
Performance matters. At least for sort of tasks like visual regression. For example, if you are running 25000 image snapshots per month you can save 20 hours of CI time per month by speeding up comparison time in just 3 seconds per snapshot.
3s * 25000 / 3600 = 20,83333 hours
Here is odiff
performance comparison with other popular visual difference solutions. We are going to compare some real-world use cases.
Lets compare 2 screenshots of full-size https://cypress.io page:
Command | Mean [s] | Min [s] | Max [s] | Relative |
---|---|---|---|---|
pixelmatch www.cypress.io-1.png www.cypress.io.png www.cypress-diff.png |
7.712 ± 0.069 | 7.664 | 7.896 | 1.82 ± 0.03 |
ImageMagick compare www.cypress.io-1.png www.cypress.io.png -compose src diff-magick.png |
8.881 ± 0.121 | 8.692 | 9.066 | 2.09 ± 0.04 |
odiff www.cypress.io-1.png www.cypress.io.png www.cypress-diff.png |
4.247 ± 0.053 | 4.178 | 4.344 | 1.00 |
Wow. Odiff is mostly 2 times faster than imagemagick and pixelmatch. And this will be even clearer if image will become larger. Lets compare a 4k image to find a difference with another 4k image:
Command | Mean [s] | Min [s] | Max [s] | Relative |
---|---|---|---|---|
ODiffBin water-4k.png water-4k-2.png water-diff.png |
4.873 ± 0.090 | 4.814 | 5.105 | 1.00 |
pixelmatch water-4k.png water-4k-2.png water-diff.png |
10.614 ± 0.162 | 10.398 | 10.910 | 2.18 ± 0.05 |
Imagemagick compare water-4k.png water-4k-2.png -compose src water-diff.png |
9.326 ± 0.436 | 8.819 | 10.394 | 1.91 ± 0.10 |
Yes it is significant improvement. And the produced difference will be the same for all 3 commands.
Changelog
If you have recently updated, please read the changelog for details of what has changed.
License
The project is licensed under the terms of MIT license
Thanks
This project was highly inspired by pixelmatch and imagemagick.
Support the project
...one day a donation button will appear here. But for now you can follow author's twitter :)