写了个图片对比的工具,小图片还可,大图片就很吃力了,求提高效率的方法

_Joker_ 2014-10-27 05:47:39
以下是我写的代码,是像素比较的,相同的地方,颜色会变暗,不同的地方,会在图片上涂红,然后赋值到界面上。
小图片还可以,大图片的话,就感觉很慢了。
求高手指点一下,给出一个比较高效快速的解决方法。


private void compareResult(Bitmap b1, Bitmap b2)
{
if (b1.Width != b2.Width || b1.Height != b2.Height)
{
return;
}
Color c1;
Color c2;
int r, g, b;
Bitmap bResult = new Bitmap(b1.Width, b1.Height);
for (int x = 0; x < b1.Width; x++)
{
for (int y = 0; y < b1.Height; y++)
{

c1 = b1.GetPixel(x, y);
c2 = b2.GetPixel(x, y);
if ((c1.R ^ c2.R) != 0 || (c1.G ^ c2.G) != 0 || (c1.B ^ c2.B) != 0)
{
bResult.SetPixel(x, y, Color.Red);
}
else
{
r = Convert.ToInt32(c1.R) - 50 >= 0 ? Convert.ToInt32(c1.R) - 50 : 0;
g = Convert.ToInt32(c1.G) - 50 >= 0 ? Convert.ToInt32(c1.G) - 50 : 0;
b = Convert.ToInt32(c1.B) - 50 >= 0 ? Convert.ToInt32(c1.B) - 50 : 0;
bResult.SetPixel(x, y, Color.FromArgb(r, g, b));
}
}
}
PictureBox1.Image = (Image)bResult;
}
...全文
311 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
jy251 2014-10-28
  • 打赏
  • 举报
回复
绑定,我想不出更好的办法,出了每个像素对比之外 另外本身大点的图片就算在windows下直接开打需要的时间都很长,我觉得这个是没办法避免的,否则3D中的渲染也就不那么耗费时间了
_Joker_ 2014-10-28
  • 打赏
  • 举报
回复
2楼,3楼的方法是真快啊 !!谢谢了
winnowc 2014-10-28
  • 打赏
  • 举报
回复
同上。处理图片想快就用LockBits拿到内存直接unsafe处理。下面代码的效率是原来的70-80倍,我的机器比较3200*1200的图片是80多ms,应该够用了。(工程需要设置允许unsafe代码)

private Bitmap compareResultFast(Bitmap b1, Bitmap b2)
{
    if (b1.Width != b2.Width || b1.Height != b2.Height)
        return null;

    var fmt = PixelFormat.Format32bppArgb;
    var result = new Bitmap(b1);
    var rect = new Rectangle(0, 0, b1.Width, b1.Height);
    BitmapData d1 = null, d2 = null;
    try
    {
        d1 = result.LockBits(rect, ImageLockMode.ReadWrite, fmt);
        d2 = b2.LockBits(rect, ImageLockMode.ReadOnly, fmt);
        UnsafeBitmapCompare(d1.Scan0, d2.Scan0, d1.Height * d1.Stride);
    }
    finally
    {
        if (d1 != null)
            result.UnlockBits(d1);
        if (d2 != null)
            b2.UnlockBits(d2);
    }
    return result;
}

private unsafe void UnsafeBitmapCompare(IntPtr dest, IntPtr src, int length)
{
    var dp = (uint*)dest; var sp = (uint*)src;
    var end = dp + length / 4;
    while (dp < end)
    {
        if (*dp == *sp || ((*dp >> 24 == 0) && (*sp >> 24 == 0)))
        {
            var r = (int)((*dp >> 16) & 0xFF) - 50;
            var g = (int)((*dp >> 8) & 0xFF) - 50;
            var b = (int)(*dp & 0xFF) - 50;
            r = r > 0 ? r : 0; g = g > 0 ? g : 0; b = b > 0 ? b : 0;
            *dp = (*dp & 0xFF000000) | (uint)(r << 16) | (uint)(g << 8) | (uint)b;
        }
        else
            *dp = 0xFFFF0000;

        dp++; sp++;
    }
}
threenewbee 2014-10-28
  • 打赏
  • 举报
回复
整个将bitmap抓入数组处理,使用unsafe和指针, 对r = Convert.ToInt32(c1.R) - 50 >= 0 ? Convert.ToInt32(c1.R) - 50 : 0;等使用位运算代替转换和条件判断

110,545

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧