找图的功能用C或C++的实现方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了找图的功能用C或C++的实现方法相关的知识,希望对你有一定的参考价值。

昨天的好像放错地方了,都没人回答。重新发了下。请问按键精灵找图的功能用C或C++如何实现。望高手指点一下。有代码最好,如果不行给点思路也可以。谢谢了。

1 #region 找图
2
3 /// <summary>
4 /// 查找图片,不能镂空
5 /// </summary>
6 /// <param name="subPic"></param>
7 /// <param name="parPic"></param>
8 /// <param name="searchRect">如果为empty,则默认查找整个图像</param>
9 /// <param name="errorRange">容错,单个色值范围内视为正确0~255</param>
10 /// <param name="matchRate">图片匹配度,默认90%</param>
11 /// <param name="isFindAll">是否查找所有相似的图片</param>
12 /// <returns>返回查找到的图片的中心点坐标</returns>
13 List<System.Drawing.Point> FindPicture(string subPic, string parPic, System.Drawing.Rectangle searchRect, byte errorRange, double matchRate = 0.9, bool isFindAll = false)
14
15 List<System.Drawing.Point> ListPoint = new List<System.Drawing.Point>();
16 var subBitmap = new Bitmap(subPic);
17 var parBitmap = new Bitmap(parPic);
18 int subWidth = subBitmap.Width;
19 int subHeight = subBitmap.Height;
20 int parWidth = parBitmap.Width;
21 int parHeight = parBitmap.Height;
22 if (searchRect.IsEmpty)
23
24 searchRect = new System.Drawing.Rectangle(0, 0, parBitmap.Width, parBitmap.Height);
25
26
27 var searchLeftTop = searchRect.Location;
28 var searchSize = searchRect.Size;
29 System.Drawing.Color startPixelColor = subBitmap.GetPixel(0, 0);
30 var subData = subBitmap.LockBits(new System.Drawing.Rectangle(0, 0, subBitmap.Width, subBitmap.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
31 var parData = parBitmap.LockBits(new System.Drawing.Rectangle(0, 0, parBitmap.Width, parBitmap.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
32 var byteArrarySub = new byte[subData.Stride * subData.Height];
33 var byteArraryPar = new byte[parData.Stride * parData.Height];
34 Marshal.Copy(subData.Scan0, byteArrarySub, 0, subData.Stride * subData.Height);
35 Marshal.Copy(parData.Scan0, byteArraryPar, 0, parData.Stride * parData.Height);
36
37 var iMax = searchLeftTop.Y + searchSize.Height - subData.Height;//行
38 var jMax = searchLeftTop.X + searchSize.Width - subData.Width;//列
39
40 int smallOffsetX = 0, smallOffsetY = 0;
41 int smallStartX = 0, smallStartY = 0;
42 int pointX = -1; int pointY = -1;
43 for (int i = searchLeftTop.Y; i < iMax; i++)
44
45 for (int j = searchLeftTop.X; j < jMax; j++)
46
47 //大图x,y坐标处的颜色值
48 int x = j, y = i;
49 int parIndex = i * parWidth * 4 + j * 4;
50 var colorBig = System.Drawing.Color.FromArgb(byteArraryPar[parIndex + 3], byteArraryPar[parIndex + 2], byteArraryPar[parIndex + 1], byteArraryPar[parIndex]);
51 ;
52 if (ColorAEqualColorB(colorBig, startPixelColor, errorRange))
53
54 smallStartX = x - smallOffsetX;//待找的图X坐标
55 smallStartY = y - smallOffsetY;//待找的图Y坐标
56 int sum = 0;//所有需要比对的有效点
57 int matchNum = 0;//成功匹配的点
58 for (int m = 0; m < subHeight; m++)
59
60 for (int n = 0; n < subWidth; n++)
61
62 int x1 = n, y1 = m;
63 int subIndex = m * subWidth * 4 + n * 4;
64 var color = System.Drawing.Color.FromArgb(byteArrarySub[subIndex + 3], byteArrarySub[subIndex + 2], byteArrarySub[subIndex + 1], byteArrarySub[subIndex]);
65
66 sum++;
67 int x2 = smallStartX + x1, y2 = smallStartY + y1;
68 int parReleativeIndex = y2 * parWidth * 4 + x2 * 4;//比对大图对应的像素点的颜色
69 var colorPixel = System.Drawing.Color.FromArgb(byteArraryPar[parReleativeIndex + 3], byteArraryPar[parReleativeIndex + 2], byteArraryPar[parReleativeIndex + 1], byteArraryPar[parReleativeIndex]);
70 if (ColorAEqualColorB(colorPixel, color, errorRange))
71
72 matchNum++;
73
74
75
76 if ((double)matchNum / sum >= matchRate)
77
78 Console.WriteLine((double)matchNum / sum);
79 pointX = smallStartX + (int)(subWidth / 2.0);
80 pointY = smallStartY + (int)(subHeight / 2.0);
81 var point = new System.Drawing.Point(pointX, pointY);
82 if (!ListContainsPoint(ListPoint, point, 10))
83
84 ListPoint.Add(point);
85
86 if (!isFindAll)
87
88 goto FIND_END;
89
90
91
92 //小图x1,y1坐标处的颜色值
93
94
95 FIND_END:
96 subBitmap.UnlockBits(subData);
97 parBitmap.UnlockBits(parData);
98 subBitmap.Dispose();
99 parBitmap.Dispose();
100 GC.Collect();
101 return ListPoint;
102
103 #endregion
参考技术A 不知道按键精灵找图片的效率如何,不过我知道准确度好像不高~~~用c++可以用GetPixel这个API来找图片,基本流程是匹配图片上的每一个点和屏幕上的每一个点,可是这样的效率不高,不过一定可以得出结果是否找到。另如“暗雪飞龙”所说,bmp图片解析是比较简单的,其他图片格式需要复杂一点的操作~~~
下面是一个简单的示例,方法比较笨,不过胜在有效:),在vc6中编译通过~~~

bool FindPic(CString FileName)

CString result = "";
CBitmap bmp;
BITMAP bm;
HBITMAP hBmp;
CDC bmpDC;
hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(),FileName,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
bmp.DeleteObject();
bmp.Attach( hBmp );
bmp.GetObject(sizeof(BITMAP),&bm);
bmpDC.CreateCompatibleDC(NULL);
bmpDC.SelectObject(&bmp); //图片DC
HDC hScreenDC = ::GetDC(NULL); //屏幕DC
bool found = false;//是否匹配到
bool next = false;//是否找下一个点
for (int i = 0;i<1280 && !found;i++)

for (int j = 0 ; j<1024 && !found;j++)

next = false;
for (int a = 0;a<30 && !next;a++)

for (int b = 0;b<30&&!next;b++)

if(GetPixel(hScreenDC,i+a,j+b) != bmpDC.GetPixel(a, b))

next = true;//找屏幕中下一个点



if (!next)//找到点

found = true;
result.Format("(%d,%d)",i,j);
return true;
break;



return false;
参考技术B 按键精灵我也用过一段时间啊,不记得有什么找图的功能,只有屏幕上取像素点。

dijkstra 算法 找图的最短路 单源最短路

基本思路是    一个path数组存路径  一个distance数组存距离   distance[k]表示 k结点到指定的初始结点的最短路   还要个collect数组收集已经被操作过的点

先初始化distance 把目标结点的子结点的距离放进去,其他的初始化为无穷大,  每次找d中未被收集到collection中的最小值,这是最重要的,有这步才能证明最后得到的是最短路,这步是贪心思想,每次找距离最小的未在collection里的结点来,保证最后得到的最小路径,这是被证明的,这步也保证了遍历所有的路径从而得到最小值,

具体体现在      比如  先对3结点操作,3结点到4结点来更新4的最短距离后,把3放进collect里  然后到5结点 它的子节点也有3 但是不用再去对3到5来更新5到目标点的最短距离了,因为5结点在后,它到目标点的距离必定比到3的距离大 而距离都是大于0的 所以不用去走这步了 所以必须要有 选最小这个思想 程序才对,所有路线才被考虑到,而且着步直接去掉了许多不用考虑的。  而且说明 有负值的 边权的图是不可以用这种算法的,因为找的最短路是错的,就是因为这儿。

 

以上是关于找图的功能用C或C++的实现方法的主要内容,如果未能解决你的问题,请参考以下文章

图的遍历和生成树求解实现 (c语言版)

用C或C++编程实现数据库的查询,添加,删除,修改功能。

无权无向图,用邻接表存储,求各个顶点之间的最小边数,求c++或c代码。十分感谢啊

数据结构C语言版 图的遍历 DFS和BFS算法,用邻接矩阵储存 急阿在线等 求大神指点

在C语言中编程实现建立无向图的邻接表,输出某个点的邻接点~!

用C或C++实现求最短路径的Dijkstra算法