C#两副图片的反差相比的C#实现

早上观察stg609 写的《Dot
Net下促成屏幕图像差别获取v2.0
》著作,想起自己原先写过的一个《我们来找茬》的玩乐帮忙工具(就是作弊器了,嘿嘿),当时也是用到了判断比较两副图片的差距效能。现将立时写的区别比较代码发上来,给我们参考参考。

眼看用的粗略实现形式就是:将两副图片同时按自然大小的小块“切分开”,再各自相比这多少个小块,倘若某个块里现身有一个不同的象素点,这就以为此块所在的岗位是有出入的否则认为是同一的,当相比较完所有小块后,两副图中间的不同之处的职位也就出来了。因为要拓展富有小块相比较,所以最坏的景观下是要扫描相比图片的具备象素点(两副图完全相同的图景时),最雅观的境况就是只扫描相比所有小块的首先点(两副图完全不一样的意况时)。

这种措施的判定精确性是基于“块”大小来控制的,也就是假设您将“块”设得过大,判断的“精确性”就越低(因为只要块里有一些不相同,就认为此块地方是有异样的),如将“块”设置得过小,则判断的“精确性”就越高,但需要时间也有可能会越多!

 

如有下边的两副图:(以下图借用了stg609 的《Dot
Net下实现屏幕图像差别获取v1.0
》作品里的截图,呵)

C# 1                    
C# 2        

           
(第一幅图片)                                                              
(第二幅图片)

 

将上边两幅图按20*20(px)大小“切分”:

 

C# 3                     C# 4

           
(第一幅图片)                                                              
(第二幅图片)

 

两副图都分别“切分”成四个20*20的小块,程序再各自对这一个小块举行判定,若是“扫描”到小块里的某个象素点是不平等的则记录此块的坐标地方并退出当前块的扫描,继续扫描下一个小块,直到所有小块“扫描”完成。

在程序处理时为加强速度,利用了Bitmap的LockBits方法,直接对图片的内存数据操作,并且“切分”图片的小块时,并不着实的“切图”,而是使用“内存指针”举办数据一定操作。如下边代码:

 

C# 5C# 6代码

                    while (h < bd1.Height && h < bd2.Height)
                    {
                        byte* p1 = (byte*)bd1.Scan0 + h * bd1.Stride;
                        byte* p2 = (byte*)bd2.Scan0 + h * bd2.Stride;

                        w = 0;
                        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);

                                    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));

                                        goto E;
                                    }
                                }
                            }
                        E:
                            w += block.Width;
                        }

                        h += block.Height;
                    }

 

 

 

演示项目代码下载:

/Files/kingthy/ImageComparer.zip

地点两幅图的反差比较后的截图:(两图中灰色与棕色框框内的小块就是注脚有出入的小块)

C# 7

 

相关文章