0

Goal: Compare two PNG images and creating a new image containing only the changes (not highlighted in red or anything), while the rest of the png is transparent.

            MagickImage newImg = new MagickImage(image2Path);

            MagickImage oldImage = new MagickImage(diffImagePath);

            oldImage.Compose = CompositeOperator.Difference;

            var diffimage = new MagickImage();

            using (var imgDiff = new MagickImage())
            {
                double diffd = newImg.Compare(oldImage, ErrorMetric.Absolute, diffimage);
            }

What I'm ending up with when comparing two identical pictures is the same, but with a little opacity.

Any help is appreciated.

EDIT: Basically what I would like to end up is this. But instead of the result having a white background, I would like it to be transparent. enter image description here

fjompen
  • 73
  • 1
  • 12
  • If the only difference is that something is transparent in the changed image, how do you want it to show? – gnud Feb 16 '21 at 12:03
  • What I mean is that I want the differences to be the same as in the picture I'm comparing with, while the rest that hasnt changed should be transparent. – fjompen Feb 16 '21 at 12:05
  • I understand that. But if the only difference is in opacity levels, how can you tell 'this is not changed' apart from 'this is changed to be transparent'? – gnud Feb 16 '21 at 12:08
  • I might've been unclear. What I'm doing is that im taking screenshots of my screen on an interval. I want to compare the new screenshot with the old one and only show what changed. There are no changes in opacity level between the two pictures. But the end result after comparing them is a picture with opacity. I would like the things that havent changed to instead be transparent while the things that has changed are as they were in the new screenshot. – fjompen Feb 16 '21 at 12:12
  • Updated my question with a picture to clarify – fjompen Feb 16 '21 at 12:15
  • Please provide separate original images – fmw42 Feb 16 '21 at 19:23

2 Answers2

0

In command line ImageMagick, this would be how to do that. Sorry, I am not a Magick.Net user. But the translation should be obvious.

Car1:

enter image description here

Car2:

enter image description here

compare -highlight-color red -lowlight-color none -compose src car1.png car2.png diff.png

enter image description here

fmw42
  • 46,825
  • 10
  • 62
  • 80
0

I find Magick.Net and ImageMagick in general annoying to use via APIs in general, because all documentation describes the command line, so you sort of have to guess how to translate into API calls.

This is one approach I managed to hobble together. Maybe there's a more elegant way.

Input:

Car with writing Car without writing

var newImg = new MagickImage(pathToCarWithWriting);
var oldImg = new MagickImage(pathToBlankCar);

// Calcluate a greyscale mask for any changed pixels.
// The mask should not have an alpha channel so it can work with Copy_Opacity
// The 'treshold' value of 60% is stolen from 
// https://stackoverflow.com/questions/38060940/how-to-create-black-and-white-images-in-magick-net
var diffMask = newImg.Clone();
diffMask.Composite(oldImg, CompositeOperator.Difference, Channels.RGB);
// Convert to greyscale
diffMask.Threshold(new Percentage(60));


var changed = newImg.Clone();
// Overlay a greyscale mask to the new image, using CopyAlpha
// (which does not copy the alpha channel when the overlay has no alpha channel, but instead treats it as a mask)
// Now only the areas that are different in newImg and oldImg will be visible in Changed.
changed.Composite(diffMask, CompositeOperator.CopyAlpha);

Result (which is transparent except for the yellow):

enter image description here

gnud
  • 77,584
  • 5
  • 64
  • 78
  • By the way, the documentation for the suprising behavior of CopyAlpha (Copy_Opacity before ImageMagick 7) is at https://legacy.imagemagick.org/Usage/compose/#copyopacity – gnud Feb 16 '21 at 22:21