Image diffing with CSS tricks


We've been hard at work delivering exciting new features in Domino. Our latest release included a lot, including the ability to import/share data sets across projects, easier ways to manage organizations of users, and improvements to how we host Jupyter notebooks, along with changes that make it easier to manage an on-premise deployment of Domino.

In this post, I wanted to share a preview of a beta feature that's still in development: the ability to compare images more intuitively.

Background & Use Case

Domino provides the ability to compare different analytical experiments you run, so you can see your actual results side-by-side, not merely the changes in your source code. This is useful if you're generating charts or other diagnostic images and varying techniques or parameters of your experiment.

This works well if your images have differences that are easy to spot visually. But if the differences are more subtle, a visual inspection may not be sufficient.

CSS-based Image Diffing

We borrowed a technique we read about here to add a new feature to our image-comparison view. Instead of two different versions of an image side-by-side, you can view one on top of the other with with an overlay that makes it easy to spot differences. Check it out:

The newer version of the image is overlaid on the older version, and we present a few knobs and dials for comparison:

  • The slider controls the opacity of the top image. Moving it back and forth lets you interactively explore the changes easily.
  • Initially, the "invert colors" option is selected. This inverts the colors of the top image. When the opacity of the top image is around 50%, the inverted color of the top image "cancels out" with the color of the bottom image. The result is that any places where the images are the same become grey, and only the differences stand out.


The CSS here is pretty basic. We use -webkit-filter: invert(...) opacity(...) to do everything we need to do. The slider and button are wired up to call this function on change:

function changeTopImage() {
            var opacity = $("#opacity-slider").val();
            var invert = $("#invert-checkbox").is(":checked") ? 100 : 0;
            $("#top-image").css("-webkit-filter", "invert(" + invert + "%) opacity(" + opacity  + "%)")

Coming soon

We'll ship this feature in an upcoming release. Stay tuned!