C# 用C语言计算图像差异#

C# 用C语言计算图像差异#,c#,.net,image,C#,.net,Image,如何生成包含其他两幅图像像素差异的System.Drawing.Image 类似于does的东西,但用C编写# 在javascript中实现的。有一个上下文混合器项目可以复制Photoshop混合模式 你知道它是被翻译成C#还是一个具有相同质量级别的类似算法吗?我还需要管理透明图像(使用alpha频道)。一个快速的谷歌搜索结果是: 如果要使用ARGB而不是RGB,可能需要进行一些编辑。如果您想获得“反向差异”效果,如在发布的Github链接中,您可以将其用于差异图像中的每个像素,等等。下面是一

如何生成包含其他两幅图像像素差异的
System.Drawing.Image

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

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


你知道它是被翻译成C#还是一个具有相同质量级别的类似算法吗?我还需要管理透明图像(使用alpha频道)。

一个快速的谷歌搜索结果是:
如果要使用ARGB而不是RGB,可能需要进行一些编辑。如果您想获得“反向差异”效果,如在发布的Github链接中,您可以将其用于差异图像中的每个像素,等等。

下面是一个快速而肮脏的实现:

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;}
        }
    }   
}
void Main()
{
var a=(位图)Image.FromFile(“image1.png”);
var b=(位图)Image.FromFile(“image2.png”);
var diff=像素diff(a,b);
}
不安全位图PixelDiff(位图a、位图b)
{
位图输出=新位图(a.Width、a.Height、PixelFormat.Format32bppArgb);
矩形rect=新矩形(Point.Empty,a.Size);
使用(var aData=a.LockBitsDisposable(rect,ImageLockMode.ReadOnly,PixelFormat.Format32bppArgb))
使用(var bData=b.LockBitsDisposable(rect、ImageLockMode.ReadOnly、PixelFormat.Format32bppArgb))
使用(var outputData=output.LockBitsDisposable(rect,ImageLockMode.ReadWrite,PixelFormat.Format32bppArgb))
{
字节*aPtr=(字节*)aData.Scan0;
字节*bPtr=(字节*)bData.Scan0;
字节*outputPtr=(字节*)outputData.Scan0;
int len=最小跨步*最小高度;
对于(int i=0;i
注:

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

谢谢你的回答,我已经测试过了,它可以工作,但有一些问题。首先,如果图像大小不同,该算法将失败。第二个问题是,diff图像的大小与原始图像的大小不同,你知道这方面有什么“完整”的实现吗?好的,结果大小是错误的,因为代码片段中有一个小错误,当你创建输出位图时,你创建的是大小为a.Width,a.Width,那么计算不同大小的图像呢?@DanielPeñalba,正如我在回答中提到的,它不包括在这个实现中。不管怎样,这种差异在diff图像中是如何表现的呢?类似这样的东西:+1我上下搜索,所以,将近100,bryncook是唯一一个带锁位的即时工作。