首页 新闻 会员 周边

C#图片差异对比,获取差异部分,其他相同地方为透明

0
悬赏园豆:30 [已解决问题] 解决于 2014-07-02 16:47
下面代码可以获取差异部分,但是相同部分为黑色,经过多次修改还是不行,
如果用像素点一个个循环设置,又耗时太久,有那位大神可以看看下面的,能有快速办法么
public static Bitmap DifCompare(Bitmap bmp1, Bitmap bmp2, Size block) { List<Rectangle> rects = new List<Rectangle>(); PixelFormat pf = PixelFormat.Format24bppRgb; Bitmap difBitmap = new Bitmap(bmp2.Width, bmp2.Height, pf); BitmapData bd1 = bmp1.LockBits(new Rectangle(0, 0, bmp1.Width, bmp1.Height), ImageLockMode.ReadWrite, pf); BitmapData bd2 = bmp2.LockBits(new Rectangle(0, 0, bmp2.Width, bmp2.Height), ImageLockMode.ReadWrite, pf); BitmapData bd3 = difBitmap.LockBits(new Rectangle(0, 0, difBitmap.Width, difBitmap.Height), ImageLockMode.ReadWrite, pf); try { unsafe { int w = 0, h = 0; ; while (h < bd1.Height && h < bd2.Height) { byte* p1 = (byte*)bd1.Scan0 + h * bd1.Stride; byte* p2 = (byte*)bd2.Scan0 + h * bd2.Stride; byte* p3 = (byte*)bd3.Scan0 + h * bd3.Stride; w = 0; Color c = Color.Transparent; while (w < bd1.Width && w < bd2.Width) { //按块大小进行扫描 for (int i = 0; i < block.Width; i++) { int wi = w + i; if (wi >= bd1.Width || wi >= bd2.Width) break; for (int j = 0; j < block.Height; j++) { int hj = h + j; if (hj >= bd1.Height || hj >= bd2.Height) break; ICColor* pc1 = (ICColor*)(p1 + wi * 3 + bd1.Stride * j); ICColor* pc2 = (ICColor*)(p2 + wi * 3 + bd2.Stride * j); ICColor* pc3 = (ICColor*)(p3 + wi * 3 + bd3.Stride * j); if (pc1->R != pc2->R || pc1->G != pc2->G || pc1->B != pc2->B) { //当前块有某个象素点颜色值不相同.也就是有差异. int bw = Math.Min(block.Width, bd1.Width - w); int bh = Math.Min(block.Height, bd1.Height - h); rects.Add(new Rectangle(w, h, bw, bh)); pc3[0] = pc2[0]; pc3[1] = pc2[1]; pc3[2] = pc2[2]; } } } } h += block.Height; } } } finally { bmp1.UnlockBits(bd1); bmp2.UnlockBits(bd2); difBitmap.UnlockBits(bd3); } return difBitmap; }
metoer的主页 metoer | 初学一级 | 园豆:8
提问于:2014-06-27 11:10
< >
分享
最佳答案
0

你的 BMP 格式有 Alpha 通道吗?

收获园豆:30
Launcher | 高人七级 |园豆:45045 | 2014-06-27 11:28

不知道使用

metoer | 园豆:8 (初学一级) | 2014-06-27 11:35

@metoer: 没有的话,在绘制的时候指定黑色为透明色。你把 BMP 的知识补习下。

Launcher | 园豆:45045 (高人七级) | 2014-06-27 11:43

@Launcher: 

   for (int i = 0; i < difBitmap.Width; i++)
        {
            for (int j = 0; j < difBitmap.Height; j++)
            {
                Color color = difBitmap.GetPixel(i, j);
                if (color.B == 0 && color.G == 0 && color.R == 0) //黑色
                {
                    difBitmap.SetPixel(i, j, System.Drawing.Color.Transparent);// 将黑色的 alpha 值 改为 0, 透明
                }
            }
        }

有这么一段代码,但是效率太低了,想在代码

 if (pc1->R != pc2->R || pc1->G != pc2->G || pc1->B != pc2->B)
                                    {}
else
{
  // 相同部分
}

相同部分设置为透明

metoer | 园豆:8 (初学一级) | 2014-06-27 11:47
其他回答(3)
0

略吊,不懂

wdwwtzy | 园豆:114 (初学一级) | 2014-06-27 16:29
0

确实是因为Format24bppRgb没有Alpha 通道,导致透明部分为黑色,需要将Format24bppRgb设置为32有通道的就可以了

metoer | 园豆:8 (初学一级) | 2014-07-02 16:47
0

markmark

allanzhong | 园豆:199 (初学一级) | 2019-08-30 21:12
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册