在判断图形A是否在图形B里存在 中,有个新手不懂的问题,请指教

chinaheart88 2013-09-08 05:35:58
C# 判断图形A是否在图形B里存在 并返回所在位置的坐标


做了下测试



Bitmap Image1 = (Bitmap)Image.FromFile(@"c:/1.BMP");


Bitmap Image2 = Image1.Clone(new Rectangle(20, 20, 50, 50), Image1.PixelFormat);


Point _Point= Zgke.MyImage.Panit.MyPanit.GetImageContains(Image1, Image2,0);


MessageBox.Show(_Point.ToString());



返回的坐标是20,20









下面是全部代码


/// <summary>
/// 判断图形里是否存在另外一个图形 并返回所在位置
/// </summary>
/// <param name="p_SourceBitmap">原始图形</param>
/// <param name="p_PartBitmap">小图形</param>
/// <param name="p_Float">溶差</param>
/// <returns>坐标</returns>
public static Point GetImageContains(Bitmap p_SourceBitmap, Bitmap p_PartBitmap,int p_Float)
{
int _SourceWidth = p_SourceBitmap.Width;
int _SourceHeight = p_SourceBitmap.Height;

int _PartWidth = p_PartBitmap.Width;
int _PartHeight = p_PartBitmap.Height;

Bitmap _SourceBitmap = new Bitmap(_SourceWidth, _SourceHeight);
Graphics _Graphics = Graphics.FromImage(_SourceBitmap);
_Graphics.DrawImage(p_SourceBitmap, new Rectangle(0, 0, _SourceWidth, _SourceHeight));
_Graphics.Dispose();
BitmapData _SourceData = _SourceBitmap.LockBits(new Rectangle(0, 0, _SourceWidth, _SourceHeight), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
byte[] _SourceByte = new byte[_SourceData.Stride * _SourceHeight];
Marshal.Copy(_SourceData.Scan0, _SourceByte, 0, _SourceByte.Length); //复制出p_SourceBitmap的相素信息

Bitmap _PartBitmap = new Bitmap(_PartWidth, _PartHeight);
_Graphics = Graphics.FromImage(_PartBitmap);
_Graphics.DrawImage(p_PartBitmap, new Rectangle(0, 0, _PartWidth, _PartHeight));
_Graphics.Dispose();
BitmapData _PartData = _PartBitmap.LockBits(new Rectangle(0, 0, _PartWidth, _PartHeight), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
byte[] _PartByte = new byte[_PartData.Stride * _PartHeight];
Marshal.Copy(_PartData.Scan0, _PartByte, 0, _PartByte.Length); //复制出p_PartBitmap的相素信息


for (int i = 0; i != _SourceHeight; i++)
{
if (_SourceHeight - i < _PartHeight) return new Point(-1, -1); //如果 剩余的高 比需要比较的高 还要小 就直接返回
int _PointX = -1; //临时存放坐标 需要包正找到的是在一个X点上
bool _SacnOver = true; //是否都比配的上
for (int z = 0; z != _PartHeight - 1; z++) //循环目标进行比较
{
int _TrueX = GetImageContains(_SourceByte, _PartByte, i * _SourceData.Stride, _SourceWidth, _PartWidth, p_Float);

if (_TrueX == -1) //如果没找到
{
_PointX = -1; //设置坐标为没找到
_SacnOver = false; //设置不进行返回
break;
}
else
{
if (z == 0) _PointX = _TrueX;
if (_PointX != _TrueX) //如果找到了 也的保证坐标和上一行的坐标一样 否则也返回
{
_PointX = -1;//设置坐标为没找到
_SacnOver = false; //设置不进行返回
break;
}
}
}
if (_SacnOver) return new Point(_PointX , i);
}
return new Point(-1, -1);
}
/// <summary>
/// 判断图形里是否存在另外一个图形 所在行的索引
/// </summary>
/// <param name="p_Source">原始图形数据</param>
/// <param name="p_Part">小图形数据</param>
/// <param name="p_SourceIndex">开始位置</param>
/// <param name="p_SourceWidth">原始图形宽</param>
/// <param name="p_PartWidth">小图宽</param>
/// <param name="p_Float">溶差</param>
/// <returns>所在行的索引 如果找不到返回-1</returns>
private static int GetImageContains(byte[] p_Source, byte[] p_Part, int p_SourceIndex, int p_SourceWidth,int p_PartWidth, int p_Float)
{
int _PartIndex = 0;
int _SourceIndex=p_SourceIndex;
for (int i = 0; i < p_SourceWidth; i++)
{
if (p_SourceWidth - i < p_PartWidth) return -1;
Color _CurrentlyColor = Color.FromArgb((int)p_Source[_SourceIndex+3], (int)p_Source[_SourceIndex + 2], (int)p_Source[_SourceIndex + 1], (int)p_Source[_SourceIndex]);
Color _CompareColoe = Color.FromArgb((int)p_Part[3], (int)p_Part[2], (int)p_Part[1], (int)p_Part[0]);
_SourceIndex += 4;

bool _ScanColor = ScanColor(_CurrentlyColor, _CompareColoe, p_Float);

if (_ScanColor)
{
_PartIndex += 4;
int _SourceRVA = _SourceIndex;
bool _Equals=true;
for (int z = 0; z != p_PartWidth-1; z++)
{
_CurrentlyColor = Color.FromArgb((int)p_Source[_SourceRVA + 3], (int)p_Source[_SourceRVA + 2], (int)p_Source[_SourceRVA + 1], (int)p_Source[_SourceRVA]);
_CompareColoe = Color.FromArgb((int)p_Part[_PartIndex + 3], (int)p_Part[_PartIndex + 2], (int)p_Part[_PartIndex + 1], (int)p_Part[_PartIndex]);

if (!ScanColor(_CurrentlyColor, _CompareColoe, p_Float))
{
_PartIndex = 0;
_Equals = false;
break;
}
_PartIndex += 4;
_SourceRVA += 4;
}
if(_Equals)return i;
}
else
{
_PartIndex = 0;
}
}
return -1;
}

/// <summary>
/// 检查色彩(可以根据这个更改比较方式
/// </summary>
/// <param name="p_CurrentlyColor">当前色彩</param>
/// <param name="p_CompareColor">比较色彩</param>
/// <param name="p_Float">溶差</param>
/// <returns></returns>
private static bool ScanColor(Color p_CurrentlyColor, Color p_CompareColor, int p_Float)
{
int _R = p_CurrentlyColor.R;
int _G = p_CurrentlyColor.G;
int _B = p_CurrentlyColor.B;

return (_R <= p_CompareColor.R + p_Float && _R >= p_CompareColor.R - p_Float) && (_G <= p_CompareColor.G + p_Float && _G >= p_CompareColor.G - p_Float) && (_B <= p_CompareColor.B + p_Float && _B >= p_CompareColor.B - p_Float);

}











==========================================


原贴在 http://blog.csdn.net/zgke/article/details/3916679





测试时出现:

错误 1 命名空间“Zgke”中不存在类型或命名空间名称“MyImage”。是否缺少程序集引用?



问题出在

Point _Point= Zgke.MyImage.Panit.MyPanit.GetImageContains(Image1, Image2,0);

原因是什么呢。各位!!!!!!!!!!
...全文
122 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
Regan-lin 2013-09-08
  • 打赏
  • 举报
回复
这个复制粘贴复制的也很没水准啊,你的路径没那图片当然会报错,把你图片放进你的路径里
chinaheart88 2013-09-08
  • 打赏
  • 举报
回复
Bitmap Image1 = (Bitmap)Image.FromFile(@"c:/1.BMP"); Bitmap Image2 = (Bitmap)Image.FromFile(@"c:/2.BMP"); ============================================================== 接着问,如果是在Image1图上截图一部份生成Image2 。保存到2.BMP. 程序就找到不了。怎么做才能认到呢?
chinaheart88 2013-09-08
  • 打赏
  • 举报
回复
引用 楼主 chinaheart88 的回复:
C# 判断图形A是否在图形B里存在 并返回所在位置的坐标 做了下测试 Bitmap Image1 = (Bitmap)Image.FromFile(@"c:/1.BMP"); Bitmap Image2 = Image1.Clone(new Rectangle(20, 20, 50, 50), Image1.PixelFormat); Point _Point= Zgke.MyImage.Panit.MyPanit.GetImageContains(Image1, Image2,0); MessageBox.Show(_Point.ToString()); 返回的坐标是20,20 下面是全部代码 /// <summary> /// 判断图形里是否存在另外一个图形 并返回所在位置 /// </summary> /// <param name="p_SourceBitmap">原始图形</param> /// <param name="p_PartBitmap">小图形</param> /// <param name="p_Float">溶差</param> /// <returns>坐标</returns> public static Point GetImageContains(Bitmap p_SourceBitmap, Bitmap p_PartBitmap,int p_Float) { int _SourceWidth = p_SourceBitmap.Width; int _SourceHeight = p_SourceBitmap.Height; int _PartWidth = p_PartBitmap.Width; int _PartHeight = p_PartBitmap.Height; Bitmap _SourceBitmap = new Bitmap(_SourceWidth, _SourceHeight); Graphics _Graphics = Graphics.FromImage(_SourceBitmap); _Graphics.DrawImage(p_SourceBitmap, new Rectangle(0, 0, _SourceWidth, _SourceHeight)); _Graphics.Dispose(); BitmapData _SourceData = _SourceBitmap.LockBits(new Rectangle(0, 0, _SourceWidth, _SourceHeight), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); byte[] _SourceByte = new byte[_SourceData.Stride * _SourceHeight]; Marshal.Copy(_SourceData.Scan0, _SourceByte, 0, _SourceByte.Length); //复制出p_SourceBitmap的相素信息 Bitmap _PartBitmap = new Bitmap(_PartWidth, _PartHeight); _Graphics = Graphics.FromImage(_PartBitmap); _Graphics.DrawImage(p_PartBitmap, new Rectangle(0, 0, _PartWidth, _PartHeight)); _Graphics.Dispose(); BitmapData _PartData = _PartBitmap.LockBits(new Rectangle(0, 0, _PartWidth, _PartHeight), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); byte[] _PartByte = new byte[_PartData.Stride * _PartHeight]; Marshal.Copy(_PartData.Scan0, _PartByte, 0, _PartByte.Length); //复制出p_PartBitmap的相素信息 for (int i = 0; i != _SourceHeight; i++) { if (_SourceHeight - i < _PartHeight) return new Point(-1, -1); //如果 剩余的高 比需要比较的高 还要小 就直接返回 int _PointX = -1; //临时存放坐标 需要包正找到的是在一个X点上 bool _SacnOver = true; //是否都比配的上 for (int z = 0; z != _PartHeight - 1; z++) //循环目标进行比较 { int _TrueX = GetImageContains(_SourceByte, _PartByte, i * _SourceData.Stride, _SourceWidth, _PartWidth, p_Float); if (_TrueX == -1) //如果没找到 { _PointX = -1; //设置坐标为没找到 _SacnOver = false; //设置不进行返回 break; } else { if (z == 0) _PointX = _TrueX; if (_PointX != _TrueX) //如果找到了 也的保证坐标和上一行的坐标一样 否则也返回 { _PointX = -1;//设置坐标为没找到 _SacnOver = false; //设置不进行返回 break; } } } if (_SacnOver) return new Point(_PointX , i); } return new Point(-1, -1); } /// <summary> /// 判断图形里是否存在另外一个图形 所在行的索引 /// </summary> /// <param name="p_Source">原始图形数据</param> /// <param name="p_Part">小图形数据</param> /// <param name="p_SourceIndex">开始位置</param> /// <param name="p_SourceWidth">原始图形宽</param> /// <param name="p_PartWidth">小图宽</param> /// <param name="p_Float">溶差</param> /// <returns>所在行的索引 如果找不到返回-1</returns> private static int GetImageContains(byte[] p_Source, byte[] p_Part, int p_SourceIndex, int p_SourceWidth,int p_PartWidth, int p_Float) { int _PartIndex = 0; int _SourceIndex=p_SourceIndex; for (int i = 0; i < p_SourceWidth; i++) { if (p_SourceWidth - i < p_PartWidth) return -1; Color _CurrentlyColor = Color.FromArgb((int)p_Source[_SourceIndex+3], (int)p_Source[_SourceIndex + 2], (int)p_Source[_SourceIndex + 1], (int)p_Source[_SourceIndex]); Color _CompareColoe = Color.FromArgb((int)p_Part[3], (int)p_Part[2], (int)p_Part[1], (int)p_Part[0]); _SourceIndex += 4; bool _ScanColor = ScanColor(_CurrentlyColor, _CompareColoe, p_Float); if (_ScanColor) { _PartIndex += 4; int _SourceRVA = _SourceIndex; bool _Equals=true; for (int z = 0; z != p_PartWidth-1; z++) { _CurrentlyColor = Color.FromArgb((int)p_Source[_SourceRVA + 3], (int)p_Source[_SourceRVA + 2], (int)p_Source[_SourceRVA + 1], (int)p_Source[_SourceRVA]); _CompareColoe = Color.FromArgb((int)p_Part[_PartIndex + 3], (int)p_Part[_PartIndex + 2], (int)p_Part[_PartIndex + 1], (int)p_Part[_PartIndex]); if (!ScanColor(_CurrentlyColor, _CompareColoe, p_Float)) { _PartIndex = 0; _Equals = false; break; } _PartIndex += 4; _SourceRVA += 4; } if(_Equals)return i; } else { _PartIndex = 0; } } return -1; } /// <summary> /// 检查色彩(可以根据这个更改比较方式 /// </summary> /// <param name="p_CurrentlyColor">当前色彩</param> /// <param name="p_CompareColor">比较色彩</param> /// <param name="p_Float">溶差</param> /// <returns></returns> private static bool ScanColor(Color p_CurrentlyColor, Color p_CompareColor, int p_Float) { int _R = p_CurrentlyColor.R; int _G = p_CurrentlyColor.G; int _B = p_CurrentlyColor.B; return (_R <= p_CompareColor.R + p_Float && _R >= p_CompareColor.R - p_Float) && (_G <= p_CompareColor.G + p_Float && _G >= p_CompareColor.G - p_Float) && (_B <= p_CompareColor.B + p_Float && _B >= p_CompareColor.B - p_Float); } ========================================== 原贴在 http://blog.csdn.net/zgke/article/details/3916679 测试时出现: 错误 1 命名空间“Zgke”中不存在类型或命名空间名称“MyImage”。是否缺少程序集引用? 问题出在 Point _Point= Zgke.MyImage.Panit.MyPanit.GetImageContains(Image1, Image2,0); 原因是什么呢。各位!!!!!!!!!!
谢谢,原来是这样。新类要NEW。
全栈极简 2013-09-08
  • 打赏
  • 举报
回复
你是复制粘贴的吧?你应该在你的项目中直接建立一个class文件并命名为MyPanit,里面有个GetImageContains方法,直接调用就行了。前面的Zgke.MyImage.Panit是人家项目中的命名空间的名称,你可以去掉。

110,532

社区成员

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

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

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