Search code examples
c#imageperformancebitmapsystem.drawing

Sequential PrintScreens Comparison, Generate a difference image?


i am developing a application that save a printscreen at a regular interval, let's say 10 seconds.

In general the images are very similar, sometimes equal, so i came with the idea to create a bitmap that represents the difference between the current printscreen and the previous one.

To achieve this, i am comparing the 2 images, pixel by pixel, and when they are equal, i am setting the pixel with a Transparent Color (in the original code, i am using Bitmap.LockBits for a better performance):

for (var x = 0; x < width; y++)
for (var y = 0; y < height; y++)
{
   var oldColor = lastPrint.GetPixel(x, y);
   var color = currentPrint.GetPixel(x, y);

   if (oldColor == color)
   {
        differencePrint.SetPixel(x, y, Color.Transparent);
   }
}

To recover the image, i get the first printscreen and replace with the sequential bitmaps.

private void MergePrints()
    {
        var lastBitmap = new BitMap(firstPrint);
        foreach (var print in prints.OrderBy(e => e.Date))
        {
            using (var difference = new Bitmap(print.Image))
            {
                 using (var grfx = Graphics.FromImage(lastBitmap))
                 {
                     grfx.DrawImage(difference, 0, 0);
                 }                 
            }

            lastBitmap.Save(print.id + ".png");
        }
        lastBitmap.Dispose();
    }

My question is: Is there a better way to generate a object that represents the difference between the 2 images, other than a new image with transparent pixels? Maybe a new class? but this class need to be persisted and of course "smaller" than a bitmap, currently i am persisting the bitmap as byte[] after comprrsing it using 7zip algorithm.


Solution

  • You can do so using the code in this answer

    It uses LockBits and is really fast. It assumes the format to be the native ARGB pixel format.

    It takes two Bitmaps as a parameter and returns the difference Bitmap.

    The 3rd parameter lets you restore the original from the difference (if you store it losslessly, Png is recommended); this was written to allow faster transmission of only the difference image, because for only small differences it allows a much better compression ratio.

    This sounds rather similar to your situation, right?

    To answer the question directly: I can't see where you could get a better compression or a handier format than from the developers of Png.. As an added bonus you can always look at the difference for testing and immediately see the amount and the distribution of the changes..