计算C#中的图像差异

我怎么能生成一个System.Drawing.Image ,其中包含两个其他图像的像素之间的差异?

类似于GitHub的东西,但用C#编写

GiHub使用的算法是在javascript中实现的。 有一个上下文混合器项目可以复制Photoshop混合模式。

您知道是否转换为C#或具有相同质量等级的类似算法? 我还需要管理透明图像 (使用alpha通道)。

谢谢

这是一个快速而又脏的实现:

 void Main() { var a = (Bitmap)Image.FromFile("image1.png"); var b = (Bitmap)Image.FromFile("image2.png"); var diff = PixelDiff(a, b); } unsafe Bitmap PixelDiff(Bitmap a, Bitmap b) { Bitmap output = new Bitmap(a.Width, a.Height, PixelFormat.Format32bppArgb); Rectangle rect = new Rectangle(Point.Empty, a.Size); using (var aData = a.LockBitsDisposable(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb)) using (var bData = b.LockBitsDisposable(rect, ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb)) using (var outputData = output.LockBitsDisposable(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb)) { byte* aPtr = (byte*)aData.Scan0; byte* bPtr = (byte*)bData.Scan0; byte* outputPtr = (byte*)outputData.Scan0; int len = aData.Stride * aData.Height; for (int i = 0; i < len; i++) { // For alpha use the average of both images (otherwise pixels with the same alpha won't be visible) if ((i + 1) % 4 == 0) *outputPtr = (byte)((*aPtr + *bPtr) / 2); else *outputPtr = (byte)~(*aPtr ^ *bPtr); outputPtr++; aPtr++; bPtr++; } } return output; } static class Extensions { public static DisposableImageData LockBitsDisposable(this Bitmap bitmap, Rectangle rect, ImageLockMode flags, PixelFormat format) { return new DisposableImageData(bitmap, rect, flags, format); } public class DisposableImageData : IDisposable { private readonly Bitmap _bitmap; private readonly BitmapData _data; internal DisposableImageData(Bitmap bitmap, Rectangle rect, ImageLockMode flags, PixelFormat format) { bitmap.CheckArgumentNull("bitmap"); _bitmap = bitmap; _data = bitmap.LockBits(rect, flags, format); } public void Dispose() { _bitmap.UnlockBits(_data); } public IntPtr Scan0 { get { return _data.Scan0; } } public int Stride { get { return _data.Stride;} } public int Width { get { return _data.Width;} } public int Height { get { return _data.Height;} } public PixelFormat PixelFormat { get { return _data.PixelFormat;} } public int Reserved { get { return _data.Reserved;} } } } 

笔记:

  • 这个实现假定两个图像具有相同的大小,可能不是这种情况......考虑到不同的大小当然可能有点困难。
  • LockBitsDisposable方法只是一个方便,如果你愿意,你可以使用标准的LockBits方法(但是当你完成时不要忘记解锁这些位)

一个快速的谷歌搜索产生了这个:

http://www.bryancook.net/2009/10/find-differences-between-images-c.html

如果你要使用ARGB而不是RGB,那么可能需要进行一些编辑。 如果你想获得“倒置差异”效果,就像发布的Github链接一样,你可以找到RGB颜色之间的差异,并将其用于差异图像中的每个像素,等等。