pixmatch is a pixel-level image comparison tool. Heavily inspired by pixelmatch, but rewritten in idiomatic Go, with zero dependencies, to speed up images comparison. Go pixmatch has support for PNG, GIF and JPEG formats. This tool also accurately detects anti-aliasing and may count it as a difference.
Format | Expected | Actual | Difference |
---|---|---|---|
JPEG | |||
GIF | |||
PNG |
Library:
go get -u github.com/dknight/go-pixmatch
CLI:
go install github.com/dknight/go-pixmatch/cmd/pixmatch
img1, err := NewImageFromPath("./samples/form-a.png")
if err != nil {
log.Fatalln(err)
}
img2, err := NewImageFromPath("./samples/form-b.png")
if err != nil {
log.Fatalln(err)
}
// Set some options.
options := NewOptions()
options.SetThreshold(0.05)
options.SetAlpha(0.5)
options.SetDiffColor(color.RGBA{0, 255, 128, 255})
// etc...
diff, err := img1.Compare(img2, options)
if err != nil {
log.Fatalln(err)
}
fmt.Println(diff)
Usage:
pixmatch [options] image1.png image2.png
Run pixmatch -h
for the list of supported options.
Example command:
pixmatch -o diff.png -aa -aacolor=00ffffff -mask ./samples/form-a.png ./samples/form-b.png
Here is included simple script to compile binaries for some architectures. If you need something special, you can easily adopt it for your needs.
./scripts/makebin.sh
Simple tests:
go test
Tests with update diff images:
UPDATEDIFFS=1 go test
Tests with full coverage:
# Terminal output
UPDATEDIFFS=1 go test -cover
# HTML output
UPDATEDIFFS=1 go test -coverprofile c.out && go tool cover -html c.out
Benchmark scripts (outputFile will be written in logs/
directory):
./scripts/benchmark.sh <outputFile> [iterations=10]
Later, it is easier to analyze it with a cool benchstat tool.
WASI Preview 1 is very unstable, everything will be changed. This is an rough example how it might work with golang <= 1.12.6.
Compile the WASM file.
cd cmd/pixmatch
GOOS=wasip1 GOARCH=wasm go build -o pixmatch.wasm main.go
Node.js exanoke file (index.js)
const fs = require('node:fs');
const {WASI} = require('node:wasi');
const imgs = ['form-a.png', 'form-b.png'];
const virtulPathWasiPath = '';
const wasi = new WASI({
version: 'preview1',
args: [virtulPathWasiPath, '-mask', '-o', 'diff.png', ...imgs],
preopens: {
'/': __dirname,
},
});
const wasmBuffer = fs.readFileSync('./pixmatch.wasm');
WebAssembly.instantiate(wasmBuffer, wasi.getImportObject()).then(
(wasmModule) => {
wasi.start(wasmModule.instance);
}
);
Run node script:
NODE_NO_WARNINGS=1 node index.js
- Anti-aliasing detection algorithm can be improved (help appreciated).
- Because of the nature of the JPEG format, comparing them is not a good idea or play with
threshold
parameter. - I have not tested this tool for 64-bit color images.
- To provide 100% compatibility with pixelmatch. Original test files are borrowed from fixtures.
- Hummingbird is taken from Wiki commons by San Diego Zoo.
- Someone on the Pixilart platform created this pixel art girl.
- Form screenshots are made using PureCSS framework.
Any help is appreciated. Found a bug, typo, inaccuracy, etc.? Please do not hesitate to make a pull request or file an issue.
MIT 2023