shigehachi
v8.0.0
Published
Compare two sets of images and generate difference images
Downloads
16
Maintainers
Readme
shigehachi (繁八)
Compare two sets of images and generate difference images
This tool reads a folder, searching for images and then tries to find matching ones from another folder. These pairs are compared and an image is created to a third folder, which visualises the differences of the first two.
Background for the name
The name of the project is for honouring the legacy of Mr Sonobe Shigehachi (園部 繁八), who was the 16th head master of Jikishinkageryu Naginatajutsu (直心影流薙刀術), which is an ancient Japanese martial art, focusing the handling of a long pole like weapon called naginata.
Getting started
Make sure you have GraphicMagick installed and available
in the PATH
, before trying to use shigehachi
. This can be tested by running for example
the following command which should provide plenty of information when successful:
gm version
The version tested of GraphicMagick is 1.3.34
.
Install the shigehachi
command line utility globally with npm.
Elevated privileges might be needed via sudo
, depending on the platform. In most cases just:
npm install --global shigehachi
Please note that the minimum supported version of Node.js is 14.15.0
, which is the active Long Term Support (LTS) version.
Run from the command line, for example getting the help output:
shigehachi -h
Compare two directories with the default comparison algorithm and store
differentiation images to a folder called images-diff
:
shigehachi -P images-previous -C images-current -O images-diff
Along with the "compare" image, there will also be a "negate" and "composite" images, which should help to determine which metric algorithm is the most suitable for the given comparison.
Comparison example
By running the following command on two screen captures of naginata.fi that were taken while adjusting paddings:
shigehachi --current-dir tests/fixtures/curr/website \
--previous-dir tests/fixtures/prev/website \
--output-dir tests/expected/website \
--match '\.(png)$' \
--metric rmse
...would result these three images, in the order of "difference", "negate", and "composite":
The previous and
current images are available at
the tests/fixtures
directory.
The file shigehachi.json
generated to the output directory, looks something similar to this:
{
"a0db9e2b1dec76cd4964bbac45daa719": {
"metric": "MeanAbsoluteError",
"normalized": {
"red": "0.0135227820",
"green": "0.0771904810",
"blue": "0.0779529725",
"opacity": "0.0982667803",
"total": "0.0667332540"
},
"absolute": {
"red": "886.2",
"green": "5058.7",
"blue": "5108.6",
"opacity": "6439.9",
"total": "4373.4"
},
"A": "tests/fixtures/prev/website/naginata-koryu.png",
"B": "tests/fixtures/curr/website/naginata-koryu.png",
"D": "tests/expected/website/naginata-koryu.png",
"N": "tests/expected/website/naginata-koryu-negate.png"
}
}
The index hash is made with md5
algorithm, from the file path string of image A.
Command line options
The output of shigehachi --help
pretty much covers all the options:
shigehachi [options]
-h, --help Help and usage instructions
-V, --version Version number, with verbosity also application name
-v, --verbose Verbose output, will print which file is currently being processed
-P, --previous-dir String Directory in which the previous images are stored - default: previous
-C, --current-dir String Directory in which the current images are stored - default: current
-O, --output-dir String Directory in which the resulting differentiation images are stored - default: diff-2019-05-15T15-22
-c, --color String Color used in the output images, such as #b10dc9 or purple - default: pink
-m, --metric String Difference calculation metric - either: mae, mse, pae, psnr, or rmse - default: pae
-s, --style String Style in which the differentiation image is created - either: assign, threshold, tint, or xor - default: tint
-p, --compose String Composition type used for creating a composite image - either: over, in, out, atop, xor, plus, minus, add, subtract, difference, divide, multiply,
bumpmap, copy, copyred, copygreen, copyblue, copyopacity, copycyan, copymagenta, copyyellow, or copyblack - default: difference
-A, --all-variations Generate diff image variations for all alternatives of metric and compose options
-M, --match String Regular expression for matching and filtering image files - default: \.png$
-l, --long-diff-name Include used metric, style and composition options in difference image file names
-r, --recursive Recursive search of images in the previous and current directories
Version 7.0.0
Be aware of using the --all-variations
option, since it will execute about 1320 commands per single image comparison pair.
Combining --version
and --verbose
(or using -Vv
) the output will also contain the name
of the application in addition to the version number.
Using in a Node.js script
Best example of the usage inside another application is inside the script that is used
for the command line interface, bin/shigehachi.js
.
Installation with npm:
npm install --save shigehachi
First include this module in your script:
const Shigehachi = require('shigehachi');
Define the options, which follow the same convention as the command line options, with the exception of being camelCased from the long versions. Below is an example of all configuration options by using their default values:
const options = {
color: 'pink',
compose: 'difference',
currentDir: 'current',
longDiffName: false,
match: '\.png$',
metric: 'pae',
outputDir: 'diffence',
previousDir: 'previous',
recursive: false,
allVariations: false,
style: 'tint',
verbose: false,
whenDone: null
};
Initialise an instance with the above options
object and call exec()
method
to generate the images:
const hachi = new Shigehachi(options);
hachi.exec();
In addition to the options used for command line, there is also a callback which gets called when the execution has been done. It gets passed one argument, which is the collection object of metrics, indexed by the current image file path.
const options = {
whenDone: function (metrics) {
console.log(JSON.stringify(metrics, null, ' '));
}
};
const hachi = new Shigehachi(options);
hachi.exec();
The metrics output looks something similar to:
{
"a0db9e2b1dec76cd4964bbac45daa719": {
"metric": "MeanAbsoluteError",
"normalized": {
"red": "0.0135227820",
"green": "0.0771904810",
"blue": "0.0779529725",
"opacity": "0.0982667803",
"total": "0.0667332540"
},
"absolute": {
"red": "886.2",
"green": "5058.7",
"blue": "5108.6",
"opacity": "6439.9",
"total": "4373.4"
},
"A": "tests/fixtures/prev/postcss.png",
"B": "tests/fixtures/curr/postcss.png",
"D": "tests/fixtures/output/postcss-mae-tint.png",
"N": "tests/fixtures/output/postcss-mae-tint-negate.png"
}
}
File matching
Please note that the command line option and the module configuration expects the match
to be a string which is passed to new RegExp()
constructor.
By default all PNG files are taken in use, with /\.png$/
, but the reason for having
the option as a regular expression, is to have much more flexibility in which file names
are filtered. Please note that while escaping characters in a string, the backward slash
needs to be escaped as well.
The current implementation does not allow to set any flags for the regular expression, but the functionality can be added with a suitable pull request.
More about JavaScript regular expressions.
Output image files and their naming
It is possible to alter the naming scheme of the images that are produced by the comparison, negation and composition steps inside the single comparison of two image files.
By default the comparison image will have the same basename as the two which are being compared.
For example prev/image.jpg
and curr/image.jpg
will produce diff/image.png
.
Please note that the generated images are always in png
format, due to quality requirements.
The negated image, which is generated from the comparison image, will have -negate
appended
to the basename, before the suffix. For example in the above case it would
be diff/image-negate.png
.
The third image is a composition of the two images that are being compared. In many cases
this is visually the most useful image, depending of the colours and composition method used.
The basename is appended with -composite
, thus in the example above diff/image-composite.png
.
These filenames can be altered via longDiffName
boolean option. By default it is set to false
and the filenames are created as explained above. In case it is set to true
, the filenames
will also be appended with the used metric
, style
, or color
, depending of the relevance
to the given method.
For example, while following the above example and setting the longDiffName
to true
, the
generated three images would become with the default options:
diff/image-pae-tint.png
diff/image-pae-tint-negate.png
diff/image-pae-tint-composite-difference.png
GraphicMagick is used underneath
The amount of supported metric algorithms, comparison styles and composition types depends of the GraphicsMagick version. Available options are listed in the source file and in the relevant GraphicsMagick documentation.
Underneath, the image comparison boils down to a command similar to this:
gm compare \
-metric mae \
-highlight-color purple \
-highlight-style xor \
-file tests/fixtures/diff/square-mae-xor.png \
tests/fixtures/prev/square.png \
tests/fixtures/curr/square.png
Output from the above command with GraphicMagick, would output something like:
Image Difference (MeanAbsoluteError):
Normalized Absolute
============ ==========
Red: 1.0000000000 65535.0
Green: 0.5019607843 32896.0
Blue: 0.4980392157 32639.0
Total: 0.6666666667 43690.0
In similar manner, with the different metric types the results vary, namely mse
, pae
, psnr
, and rmse
:
Image Difference (MeanSquaredError):
Normalized Absolute
============ ==========
Red: 1.0000000000 65535.0
Green: 0.2519646290 16512.5
Blue: 0.2480430604 16255.5
Total: 0.5000025631 32767.7
Image Difference (PeakAbsoluteError):
Normalized Absolute
============ ==========
Red: 1.0000000000 65535.0
Green: 0.5019607843 32896.0
Blue: 0.4980392157 32639.0
Total: 1.0000000000 65535.0
Image Difference (PeakSignalToNoiseRatio):
PSNR
======
Red: 0.00
Green: 5.99
Blue: 6.05
Total: 3.01
Image Difference (RootMeanSquaredError):
Normalized Absolute
============ ==========
Red: 1.0000000000 65535.0
Green: 0.5019607843 32896.0
Blue: 0.4980392157 32639.0
Total: 0.7071085936 46340.4
Contributing
"A Beginner's Guide to Open Source: The Best Advice for Making your First Contribution".
Also there is a blog post about "45 Github Issues Dos and Don’ts".
Linting is done with ESLint and can be executed with npm run lint
.
There should be no errors appearing after any JavaScript file changes.
Unit tests are written with tape
and can be executed with npm test
.
Code coverage is inspected with nyc
and
can be executed with npm run coverage
after running npm test
.
Please make sure it is over 90% at all times.
Version history
License
Copyright (c) Juga Paazmaya [email protected]
Licensed under the MIT license.