两副图片的差异比较的C#实现
2009-12-16 16:34
351 查看
早上看到stg609 写的《Dot Net下实现屏幕图像差异获取v2.0》文章,想起自己以前写过的一个《大家来找茬》的游戏辅助工具(就是作弊器了,嘿嘿),当时也是用到了判断比较两副图片的差异功能。现将当时写的差异比较代码发上来,给大家参考参考。
当时用的简单实现方法就是:将两副图片同时按一定大小的小块“切分开”,再分别比较这些小块,如果某个块里出现有一个不同的象素点,那就认为此块所在的位置是有差异的否则认为是相同的,当比较完所有小块后,两副图之间的不同之处的位置也就出来了。因为要进行所有小块比较,所以最坏的情况下是要扫描比较图片的所有象素点(两副图完全一样的情况时),最理想的情况就是只扫描比较所有小块的第一点(两副图完全不一样的情况时)。
这种方法的判断精确性是根据“块”大小来决定的,也就是如果你将“块”设得过大,判断的“精确性”就越低(因为只要块里有一点不相同,就认为此块位置是有差异的),如将“块”设置得过小,则判断的“精确性”就越高,但需要时间也有可能会越多!
如有下面的两副图:(以下图借用了stg609 的《Dot Net下实现屏幕图像差异获取v1.0》文章里的截图,呵)
代码
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
上面两幅图的差异比较后的截图:(两图中蓝色与红色框框内的小块就是表明有差异的小块)
当时用的简单实现方法就是:将两副图片同时按一定大小的小块“切分开”,再分别比较这些小块,如果某个块里出现有一个不同的象素点,那就认为此块所在的位置是有差异的否则认为是相同的,当比较完所有小块后,两副图之间的不同之处的位置也就出来了。因为要进行所有小块比较,所以最坏的情况下是要扫描比较图片的所有象素点(两副图完全一样的情况时),最理想的情况就是只扫描比较所有小块的第一点(两副图完全不一样的情况时)。
这种方法的判断精确性是根据“块”大小来决定的,也就是如果你将“块”设得过大,判断的“精确性”就越低(因为只要块里有一点不相同,就认为此块位置是有差异的),如将“块”设置得过小,则判断的“精确性”就越高,但需要时间也有可能会越多!
如有下面的两副图:(以下图借用了stg609 的《Dot Net下实现屏幕图像差异获取v1.0》文章里的截图,呵)
代码
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#实现
- 如何在C#中实现图片缩放
- 怎么在c#_winform实现图片上传功能
- C#图片压缩的实现方法
- C#实现SQL SERVER数据库备份的两种方法比较
- C# :实现水印与图片合成,并利用Graphics 压缩图像质量 , (委托实现listBox的动态添加提示)
- C#抽象工厂模式的几种实现方法及比较
- C#给图片加水印的简单实现方法
- C#实现图片特效 ( 二)
- C#PDA智能程序图片动态变化进度条设计及实现
- c#实现远程图片下载
- SSD及其不同主网络实现的性能差异比较
- c#比较两个数组的差异
- C# 实现渐变透明图片
- c#实现简单的windows服务实例--清除图片缓存定时器服务
- C#实现给图片加透明度水印
- C#抽象工厂模式的几种实现方法及比较
- c#+oracle实现读取图片并显示在picturebox中
- C#如何实现图片的剪裁并保存
- 单例模式的五个实现方法比较 via C#