Hi, I'm Ray

26 Feb, 2020     26 Feb, 2020

C#: Quick and easy generating a differential image

Programming, .NET, C#

I’ve been working on a proof-of-concept recently with an unusually high amount of R&D. This post comes from one of those R&D mini-tasks.

I wanted to take two images (A and B), compare the two then generate a new image (A1) with just the differences. I want to be able to stack images A and A1 on top of each other to get B. Think in terms of editing layers in Photoshop or rendering images on top of previous images.

A original  B original  A1 original

I had a quick look on NuGet and the usual places on the Web. I saw solutions for detection-highlighting and code for calculating the percentage difference. What I wanted was much simpler than any of that.

So, I wrote my own. It took about 20 minutes.

I understand that there is likely a better way to do this but this is what I have for now.

Let’s get started.

The Idea

What my code does is compare two images pixel-by-pixel row-by-row. Any pixel that is different is copied to a differential image. This diff-image starts off transparent so it can be stacked on top of the original image.

The Code


protected Bitmap generateDiffImage(Bitmap image1, Bitmap image2)
{
	if (image1 == null) return null;
	if (image2 == null) return null;
	if (!image1.HorizontalResolution.Equals(image2.HorizontalResolution)) return null;
	if (!image1.VerticalResolution.Equals(image2.VerticalResolution)) return null;
	if (!image1.Width.Equals(image2.Width)) return null;
	if (!image1.Height.Equals(image2.Height)) return null;

	Bitmap newBitmap = new Bitmap(image2.Width, image2.Height, image2.PixelFormat);
	newBitmap.SetResolution(image2.HorizontalResolution, image2.VerticalResolution);
	newBitmap.MakeTransparent();

	for (var x = 0; x < image1.Width; x++)
	{
		for (var y = 0; y < image1.Height; y++)
		{
			var firstPixel = image1.GetPixel(x, y);
			var secondPixel = image2.GetPixel(x, y);

			if (firstPixel != secondPixel)
			{
				newBitmap.SetPixel(x, y, secondPixel);
			}
		}
	}

	return newBitmap;
}

That’s it. I hope someone finds this useful.