dssim: an image similarity metric that tries to look the way a person looks
Image similarity comparison simulating human perception (multiscale SSIM in Rust)
At a glance
- What is it?
- dssim is a Rust command line tool and library that measures how different two images look, using a multi-scale variant of SSIM in linear-light RGB and Lab colour space, with no OpenCV or MATLAB. This looks at what the number means, how to use it fairly, and what it costs to embed.
- Who is it for?
- dssim fits a team choosing between image codecs or checking a lossy pipeline, that needs a metric that reflects perceived difference rather than byte equality, and that wants a single binary or a Rust, C or WASM library. It does not fit a workflow that needs pixel-exact detection of a specific changed region, and it is the wrong choice for a proprietary product unless you buy the commercial licence, since the open source terms are AGPL-3.0.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 22 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The number is a distance, not a percentage
dssim computes the similarity or dissimilarity between two or more PNG and JPEG images using an algorithm approximating human vision, based on a variant of the SSIM algorithm by Wang and colleagues.
The first thing to understand is the scale. The value returned is 1/SSIM minus 1, where 0 means identical image and anything above 0, unbounded, is the amount of difference. The documentation is emphatic on two points: the amount of difference goes from 0 to infinity, and it is not a percentage. It also warns that the values are not directly comparable with other tools.
That last point is the one that catches people out. A number that reads like a score invites comparison with another tool's score, and there is no mapping between them. A dssim value of 0.02 says something specific about two images under this metric and nothing about two other images under a different metric.
The tool is written in Rust, and the repository is a Cargo workspace with the binary in the root package and the reusable part in a `dssim-core` member directory. The project's homepage is kornel.ski/dssim.
Why multi-scale SSIM and linear-light scaling
The algorithm differences from plain SSIM are the substance of the project, and the documentation lists them.
The comparison is done on multiple weighted scales, based on IWSSIM, to measure features of different sizes. The stated reason is that a single-scale SSIM is biased towards differences smaller than its Gaussian kernel, which is a real property of the original method and a common source of misleading results.
Scaling is done in linear-light RGB, to model the physical effects of viewing distance and lenses. The documentation argues that scaling in sRGB or Lab would have incorrect gamma and would mask distortions caused by chroma subsampling. That last point is worth internalising, because chroma subsampling is exactly the kind of defect that a naive pixel metric misses and a human eye catches.
The colour space is L*a*b* for the SSIM algorithm itself, which the documentation says measures brightness and colour much better than metrics built on an average of RGB channels. The a and b channels are compared with lower spatial precision, to simulate the eye's higher sensitivity to brightness than to colour changes. The score is pooled using mean absolute deviation, and you can get per-pixel SSIM from the API if you want to implement custom pooling, which is how you would build a difference heatmap of your own rather than using the built-in one.
The comparison also supports the alpha channel and images with colour profiles, and it takes advantage of multi-core CPUs.
The command line, and the difference image
Usage is two filenames and an output number:
dssim file-original.png file-modified.pngThe output looks like `0.02341`, smaller is better, followed by a filename. Supplying multiple filenames compares them all against the first one:
dssim file.png modified1.png modified2.png modified3.pngAnd a difference visualisation can be written out with the `-o` flag:
dssim -o difference.png file.png file-modified.pngThat last one is more useful than it sounds. A single scalar tells you that two images differ; a difference image tells you where, which is the difference between a metric and a diagnostic tool. If a codec is producing artefacts in a specific region, the scalar will tell you the artefacts are there and the image will tell you they are in the corner.
There is a detail in the version reporting that is easy to miss and matters for reproducibility. The documentation says that when you quote results, please include the DSSIM version, because the scale has changed between versions, and that the version is printed when you run `dssim -h`. A benchmark result without its version number is not a comparable number, because the scale moved under it.
Comparing two codecs means fixing one variable
The documentation gives explicit guidance on how to use the metric when comparing compression codecs, and it is the part most users need.
There are two valid protocols. You can compress images to the same file size and then use dssim to see which result is closest to the original. Or you can compress images to the same dssim value and compare the file sizes to see how much size gain each option gives.
Both are sound, and mixing them is the mistake. Comparing codec A at one file size against codec B at another tells you nothing, because quality and size are being traded at once. The point of a perceptual metric is to hold one of them still so the other becomes readable.
The project also links a longer piece on benchmarking image compression, and the repository contains a `clic-2021/` directory and a `benches/` directory, which suggests the tool is used against the CLIC image compression benchmark as well as in its own benchmarks.
One more caution is repeated in the usage section: be mindful about colour profiles in the images. Different profiles, or a lack of support for profiles in other tools, can make images appear different even when the pixels are the same. In other words, part of the difference dssim reports can be a configuration artefact rather than an encoding defect, and a benchmark that ignores profiles is measuring the wrong thing.
As a library: Rust, C and WASM
The tool is usable as a library in C, Rust and WASM, and the documentation covers the C path in detail because it is the least obvious.
For C, the instruction is to make sure you build the `dssim-core` library project rather than the parent `dssim` binary project:
cd dssim-core
rustup update
cargo build --releaseThat produces `target/release/libdssim_core.a` to link into your project, and you use the `dssim.h` header included in the repository. There is a more involved but more proper method on Linux, which uses the `cargo-c` tooling:
cargo install cargo-c
cargo cinstall --release --destdir=/ --prefix=/usr/libThat installs `libdssim.so` into `/usr/lib` and makes `dssim` available to `pkg-config`, which is the difference between linking this library the way a distro expects and bolting a static archive onto your build.
For WASM, there is one compatibility rule. The `threads` Cargo feature is enabled by default, and for compatibility with single-threaded WASM runtimes you disable default features:
dssim-core = { version = "3.2", default-features = false }The Rust version requirement is worth noting. The readme says you will need Rust 1.63 or later, while the manifest in the repository declares `rust-version = "1.90"` with edition 2024, which is the figure the build will actually enforce.
Where dssim is the wrong tool
The limits are about what the metric can answer and about what it costs to ship.
The first limit is that dssim answers a question about whole images. It gives you one number for a pair of files, and even with the per-pixel API you would be building your own analysis on top. If your requirement is to detect that one specific region changed, or to find the coordinates of an edit, this is a similarity metric, not a diff tool, and the per-pixel score is a building block rather than a report.
The second is that the metric is relative and unbounded, and the documentation says the values are not comparable with other tools. That makes dssim good for answering a question of the form which of these two images is closer to the original, and poor for answering a question of the form is this image acceptable, because there is no threshold documented and no percentage to quote. Any threshold you adopt is your own, and it will be tied to a version.
The third is the licence, and this is the one that decides the adoption question for a commercial product. DSSIM is dual-licensed under AGPL or a commercial licence, and the commercial option is offered through a separate site. AGPL-3.0 is network copyleft with a broad trigger, and for a tool you would embed in a service, that obligation is a serious commercial consideration rather than a formality. A team that wants the algorithm in a proprietary pipeline needs the commercial licence.
The fourth is the release cadence. The tags show 3.4.0, titled 20% faster, on 2025-03-05, and 3.2.3 and 3.2.0 back in 2022, while the manifest already carries version 3.5.1 and the last push to the repository was on 2026-10-01. The work is happening, but the version numbers move slowly, and given that the scale changes between versions, a pinned version in a benchmark harness is a good idea.
The fifth is the input format. The tool reads PNG and JPEG, with AVIF and WebP behind cargo features, `avif` and `webp`, and there are separate features for the JPEG decoder, `mozjpeg` for a libjpeg-turbo derivative closer to the reference decoder, and `lcms2-static` to use lcms2 instead of moxcms for colour management. Those features exist because image decoding differences change the numbers, which is the same class of problem as the colour profile caveat.
Editorial conclusion
dssim fits a team choosing between image codecs or checking a lossy pipeline, that needs a metric that reflects perceived difference rather than byte equality, and that wants a single binary or a Rust, C or WASM library. It does not fit a workflow that needs pixel-exact detection of a specific changed region, and it is the wrong choice for a proprietary product unless you buy the commercial licence, since the open source terms are AGPL-3.0. Before you quote a score, record the dssim version, because the documentation states the scale has changed between versions, and check your images carry the same colour profiles, since differing profiles alone can make identical pixels look different.
Frequently asked questions
What does a dssim score mean?
The value returned is 1/SSIM minus 1, where 0 means an identical image and anything above 0, unbounded, is the amount of difference. It is not a percentage, and the documentation states the values are not directly comparable with other tools.
How do I compare two image compression codecs fairly with dssim?
Either compress the images to the same file size and use dssim to see which is closest to the original, or compress them to the same dssim value and compare the resulting file sizes. When you quote a result, include the dssim version, because the scale has changed between versions.
Can I use dssim as a C library?
Yes. Build the `dssim-core` library project rather than the parent binary project, either with `cargo build --release` to get `target/release/libdssim_core.a` together with the `dssim.h` header, or on Linux with `cargo cinstall --release --destdir=/ --prefix=/usr/lib` to install `libdssim.so` and make it available to `pkg-config`.
How do I build dssim from source?
Clone the repository, make sure you have a recent Rust toolchain, and run `cargo build --release`, which produces `./target/release/dssim`. The readme mentions Rust 1.63 or later, while the manifest declares `rust-version = "1.90"` with edition 2024.
What licence does dssim use and can I use it commercially?
DSSIM is dual-licensed under AGPL or a commercial licence. The AGPL option means the copyleft obligations reach users who interact with the software over a network, so embedding it in a proprietary service normally means buying the commercial licence.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/kornelski-dssim)Was this useful?