Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
117 views
in Technique[技术] by (71.8m points)

c# - How to get difference between 2 images and save it to an image

And what i mean by the title is I have 2 images - each one is from a different time ( from screen cap) i want to get the difference between the two make all the same parts transparent, send the difference to a client and place it on top of an image that he has

Don't worry about the sending part - I have covered that. The thing I need help is how to get the difference, save it to an image / stream / byte array and merging it to one image.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You create and fill a target Bitmap.

Do try to use LockBits if performance is too bad. Using a library should be even faster.

Here is a quick piece of code; you pass in two Bitmaps and the Color the differences should be painted in, e.g. Color.Red or Color.Transparent.

It returns the difference Bitmap or null if the Bitmap Sizes don't match.

public Bitmap getDifferencBitmap(Bitmap bmp1, Bitmap bmp2, Color diffColor)
{
    Size s1 = bmp1.Size;
    Size s2 = bmp2.Size;
    if (s1 != s2) return null;

    Bitmap bmp3 = new Bitmap(s1.Width, s1.Height);

    for (int y = 0; y < s1.Height; y++)
        for (int x = 0; x < s1.Width; x++)
        {
            Color c1 =    bmp1.GetPixel(x, y);
            Color c2 =    bmp2.GetPixel(x, y);
            if (c1 == c2) bmp3.SetPixel(x, y, c1);
            else          bmp3.SetPixel(x, y, diffColor);
        }
    return bmp3;
}

You could call it like this:

Bitmap bmp1 = new Bitmap(filepath1);
Bitmap bmp2 = new Bitmap(filepath2);
Bitmap bmp3 = getDifferencBitmap(bmp1, bmp2, Color.Transparent);

bmp3.Save(filepath3, System.Drawing.Imaging.ImageFormat.Png);

bmp1.Dispose();
bmp2.Dispose();
bmp3.Dispose();

Make sure you dispose of the Bitmaps when you are done with them!

Of course you can easily change the logic to make identical parts Transparent and non-identical parts whatever.. I assumed you really wanted to show the differences, though.

Here is a post which contains the code for a LockBits version; you just would need to change the inner loop's code to this:

    for (int x = 0; x < s1.Width; x++)
    {
        int index1 = y * bmp1Data.Stride + x * bpp1;
        int index2 = y * bmp2Data.Stride + x * bpp2;
        int index3 = y * bmp3Data.Stride + x * bpp3;
        Color c1, c2;
        if (bpp1 == 4)
                c1 = Color.FromArgb(data1[index1 + 3], data1[index1 + 2], data1[index1 + 1], data1[index1 + 0]);
        else  c1 = Color.FromArgb(255, data1[index1 + 2], data1[index1 + 1], data1[index1 + 0]);
        if (bpp1 == 4)
                c2 = Color.FromArgb(data2[index2 + 3], data2[index2 + 2], data2[index2 + 1], data2[index2 + 0]);
        else  c2 = Color.FromArgb(255, data2[index2 + 2], data2[index2 + 1], data2[index2 + 0]);
        Color putColor = (c1 == c2 ? c1 : diffColor);

        data3[index3 + 0] = putColor.B;
        data3[index3 + 1] = putColor.G;
        data3[index3 + 2] = putColor.R;
        data3[index3 + 3] = putColor.A;
    }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...