看流星社区

 找回密码
 注册账号
查看: 3294|回复: 0

[易语言源码] C++ 高效屏幕找图 函数源码 终极版 透明找图 容错

[复制链接]

该用户从未签到

发表于 2019-5-29 20:20:27 | 显示全部楼层 |阅读模式

C++ 高效屏幕找图 函数源码 终极版 透明找图 容错



  1. #include "iostream.h"
  2. char   *lpBufscr,*lpBufbmp;
  3. BITMAP   bb,bm; //bb=屏幕  bm=图片
  4. DWORD   dwX,dwY;

  5. struct Points
  6. {
  7.         POINT pts;
  8.         struct Points *next;
  9. };

  10. void GetScreenData(int dx,int dy)
  11. {

  12.         HBITMAP   hBitmap,hOld;
  13.         HDC   hDC,hcDC;
  14.         BITMAPINFO   b;
  15.         HANDLE   hp;

  16. //        DWORD   dwX,dwY;
  17.         dwX=GetSystemMetrics(SM_CXSCREEN);
  18.         dwY=GetSystemMetrics(SM_CYSCREEN);
  19.         dwX=min(dwX,(unsigned)dx);
  20.         dwY=min(dwY,(unsigned)dy);
  21.         hDC=::GetWindowDC(NULL);
  22.         hcDC=CreateCompatibleDC(hDC);
  23.         hBitmap=CreateCompatibleBitmap(hDC,dwX,dwY);
  24.         hOld=(HBITMAP)SelectObject(hcDC,hBitmap);
  25.         BitBlt(hcDC,0,0,dwX,dwY,hDC,0,0,SRCCOPY);

  26.         bb.bmWidth=dwX;
  27.         bb.bmHeight=dwY;
  28.         bb.bmPlanes=1;
  29.         bb.bmWidthBytes=bb.bmWidth*3;
  30.         bb.bmBitsPixel=3;
  31.         bb.bmType=0;
  32.         b.bmiHeader.biSize   =   sizeof(BITMAPINFOHEADER);
  33.         b.bmiHeader.biWidth=dwX;
  34.         b.bmiHeader.biHeight=dwY;
  35.         b.bmiHeader.biPlanes   =   1;
  36.         b.bmiHeader.biBitCount   =24;
  37.         b.bmiHeader.biCompression   =   BI_RGB;
  38.         b.bmiHeader.biSizeImage   =   0;
  39.         b.bmiHeader.biXPelsPerMeter   =   0;
  40.         b.bmiHeader.biYPelsPerMeter   =   0;
  41.         b.bmiHeader.biClrUsed   =   0;
  42.         b.bmiHeader.biClrImportant   =   0;
  43.         b.bmiColors[0].rgbBlue=8;
  44.         b.bmiColors[0].rgbGreen=8;
  45.         b.bmiColors[0].rgbRed=8;
  46.         b.bmiColors[0].rgbReserved=0;

  47.         hp=GetProcessHeap();
  48.         lpBufscr=(char *)HeapAlloc(hp,HEAP_ZERO_MEMORY,bb.bmHeight*bb.bmWidth*4);
  49.         GetDIBits(hcDC,hBitmap,0,dwY,lpBufscr,&b,DIB_RGB_COLORS);

  50.         ReleaseDC(NULL,hDC);   
  51.         DeleteDC(hcDC);   
  52.         DeleteObject(hBitmap);   
  53.         DeleteObject(hOld);   
  54. //        HeapFree(hp,0,lpBufscr);

  55. }

  56. void GetBmpData(LPCTSTR lpszName)
  57. {
  58.         HANDLE hp;
  59.         HDC hdc,hdcmem;
  60.         HBITMAP hBm;
  61.         BITMAPINFO   b;
  62.         hBm=(HBITMAP)LoadImage(NULL,/*"c:\\1.bmp"*/lpszName,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_LOADFROMFILE);
  63.         GetObject(hBm,sizeof(BITMAP),(LPVOID)&bm);
  64.         hdc=::GetWindowDC(NULL);
  65.         hdcmem=CreateCompatibleDC(hdc);
  66.         SelectObject(hdcmem,hBm);
  67.         BitBlt(hdcmem,0,0,bm.bmWidth,bm.bmHeight,hdcmem,0,0,SRCCOPY);

  68.         b.bmiHeader.biSize   =   sizeof(BITMAPINFOHEADER);
  69.         b.bmiHeader.biWidth=bm.bmWidth;
  70.         b.bmiHeader.biHeight=bm.bmHeight;
  71.         b.bmiHeader.biPlanes   =   1;
  72.         b.bmiHeader.biBitCount   =24;
  73.         b.bmiHeader.biCompression   =   BI_RGB;
  74.         b.bmiHeader.biSizeImage   =   0;
  75.         b.bmiHeader.biXPelsPerMeter   =   0;
  76.         b.bmiHeader.biYPelsPerMeter   =   0;
  77.         b.bmiHeader.biClrUsed   =   0;
  78.         b.bmiHeader.biClrImportant   =   0;
  79.         b.bmiColors[0].rgbBlue=8;
  80.         b.bmiColors[0].rgbGreen=8;
  81.         b.bmiColors[0].rgbRed=8;
  82.         b.bmiColors[0].rgbReserved=0;

  83.         hp=GetProcessHeap();
  84.         lpBufbmp=(char *)HeapAlloc(hp,HEAP_ZERO_MEMORY,bm.bmHeight*bm.bmWidth*4);
  85.         GetDIBits(hdc,hBm,0,bm.bmHeight,lpBufbmp,&b,DIB_RGB_COLORS);

  86.         DeleteObject(&hBm);
  87.         DeleteDC(hdc);
  88.         DeleteDC(hdcmem);
  89. }

  90. //释放lpBuf
  91. int ReleaseLP()
  92. {
  93.         HANDLE hp=GetProcessHeap();
  94.         HeapFree(hp,0,lpBufscr);
  95.         HeapFree(hp,0,lpBufbmp);
  96.         return 0;
  97. }


  98. int GetScrPixel(int x,int y)//获取屏幕颜色
  99. {

  100.         if(x<0 || x>(int)dwX || x<0 || x>(int)dwY)return-1;
  101.         BYTE   bBlue=lpBufscr[bb.bmWidthBytes*(dwY-y-1) + bb.bmBitsPixel*x + 0];
  102.         BYTE   bGreen=lpBufscr[bb.bmWidthBytes*(dwY-y-1) + bb.bmBitsPixel*x + 1];
  103.         BYTE   bRed=lpBufscr[bb.bmWidthBytes*(dwY-y-1) + bb.bmBitsPixel*x + 2];

  104.         COLORREF   color=RGB(bBlue,bGreen,bRed);
  105.         return int(color);
  106. }

  107. int GetBmpPixel(int x,int y)//获取位图颜色
  108. {
  109.         if(x<0 || x>(int)dwX || x<0 || x>(int)dwY)return-1;
  110.         BYTE   bBlue=lpBufbmp[bm.bmWidthBytes*(bm.bmHeight-y-1) + bm.bmBitsPixel*x/8 + 0];
  111.         BYTE   bGreen=lpBufbmp[bm.bmWidthBytes*(bm.bmHeight-y-1) + bm.bmBitsPixel*x/8 + 1];
  112.         BYTE   bRed=lpBufbmp[bm.bmWidthBytes*(bm.bmHeight-y-1) + bm.bmBitsPixel*x/8 + 2];

  113.         COLORREF   color=RGB(bBlue,bGreen,bRed);
  114.         return int(color);
  115.         //return lpBufbmp[1];
  116. }


  117. //查找矩形区域内颜色值为 color的点
  118. //从左往右逐行往下找
  119. //找到返回1,并将坐标赋值给参数(fx,fy),找不到则返回0
  120. int FindColor(int x1,int y1,int x2,int y2,int color,int &fx,int &fy)
  121. {
  122.         GetScreenData(x2,y2);
  123.         fx=fy=-1;
  124.         int xtmp=x1;
  125.         for(;y1<y2;y1++)
  126.         {
  127.                 for(x1=xtmp;x1<=x2;x1++)
  128.                         {
  129.                                 if(GetScrPixel(x1,y1)==color)
  130.                                 {
  131.                                         fx=x1;
  132.                                         fy=y1;
  133.                                         ReleaseLP();
  134.                                         return 1;
  135.                                 }
  136.                         }
  137.         }
  138.         ReleaseLP();
  139.         return 0;
  140. }

  141. POINT FindFirstPoint(int x1,int y1,int x2,int y2)
  142. {
  143.         int color=GetBmpPixel(0,0);
  144.         POINT pt;
  145.         pt.x=-1;
  146.         pt.y=-1;
  147.         int fx,fy,xtmp=x1;;
  148.         fx=fy=-1;
  149.         for(;y1<y2;y1++)
  150.                 for(x1=xtmp;x1<x2;x1++)
  151.                         {
  152.                                 if(GetScrPixel(x1,y1)==color)
  153.                                 {
  154.                                         pt.x=x1;
  155.                                         pt.y=y1;
  156.                                         return pt;
  157.                                 }
  158.                         }
  159.         return pt;
  160. }


  161. //比较屏幕pt点位图矩形大小的所有颜色和位置是否与位图相同
  162. int Compare(POINT pt)
  163. {
  164.         int x,y;
  165.         if((unsigned)bm.bmHeight>dwY-pt.y)return 0;
  166.         for(y=0;y<bm.bmHeight-1;y++)
  167.         {
  168.                 for(x=0;x<bm.bmWidth-1;x++)
  169.                 {
  170.                         if(GetBmpPixel(x,y)==GetScrPixel(pt.x+x,pt.y+y))
  171.                         {
  172.                        
  173.                        
  174.                         }
  175.                         else
  176.                         {
  177.                                 return 0;
  178.                         }
  179.                 }
  180.         }
  181.         return 1;
  182. }

  183. //从数据char *lpBufscr中查找*lpBufbmp;
  184. int FindBmpBuf(int x1,int y1,int x2,int y2,int &fx,int &fy)
  185. {
  186.         POINT pt,pttmp;
  187.         fx=-1;
  188.         fy=-1;

  189.         pt=FindFirstPoint(x1,y1,x2,y2);
  190.         if(Compare(pt)){fx=pt.x;fy=pt.y;return 1;}
  191.        
  192.         else//出现第一个点找到后却并不与位图吻合
  193.                 {
  194.                         pttmp.y=pt.y+1;
  195.                         while(pt=FindFirstPoint(pt.x+1,pt.y,x2,pt.y+1) ,pt.x>=0)
  196.                         {
  197.                                 if(Compare(pt)){fx=pt.x;fy=pt.y;return 1;}
  198.                         }
  199.                         while(pt=FindFirstPoint(x1,pttmp.y,x2,y2) ,pt.x>=0)
  200.                         {
  201.                                 if(Compare(pt)){fx=pt.x;fy=pt.y;return 1;}
  202.                                 else
  203.                                 {
  204.                                         pttmp.y=pt.y+1;
  205.                                         while(pt=FindFirstPoint(pt.x+1,pt.y,x2,pt.y+1) ,pt.x>=0)
  206.                                                 if(Compare(pt)){fx=pt.x;fy=pt.y;return 1;}
  207.                                 }
  208.                         }
  209.                 }
  210.         return 0;
  211. }

  212. //从矩形x1,y1,x2,y2内查找与位图lpszName完全匹配的起始点
  213. //若找到,(fx,fy)为图片第一次出现的左上角顶点,并返回1
  214. //若找不到,(fx,fy)=(-1,-1)并返回0
  215. int FindBmp(int x1,int y1,int x2,int y2,LPCTSTR lpszName,int &fx,int &fy)
  216. {
  217.         GetBmpData(lpszName);
  218.         GetScreenData(x2,y2);

  219.         FindBmpBuf(x1,y1,x2,y2,fx,fy);

  220.         ReleaseLP();
  221.         if(fx>0)return 1;
  222.         return 0;

  223. }

  224. //比较屏幕pt点位图矩形大小的所有颜色和位置是否与位图条件匹配
  225. //位图backcolor颜色点忽略,颜色偏差errorcolor,允许不匹配点的个数errorcount
  226. //比较成功返回1,否则返回0
  227. int CompareEx(POINT pt,int backcolor,int errorcolor,int errorcount)
  228. {
  229.         int x,y,colorB,colorS,count=0;
  230.         if((unsigned)bm.bmHeight>dwY-pt.y)return 0;
  231.         for(y=0;y<bm.bmHeight-1;y++)
  232.                 for(x=0;x<bm.bmWidth-1;x++)
  233.                 {
  234.                         colorB=GetBmpPixel(x,y);
  235.                         colorS=GetScrPixel(pt.x+x,pt.y+y);
  236.                         if(colorB==colorS || colorB==backcolor);
  237.                         else
  238.                         {
  239.                                 if( abs(GetRValue((COLORREF)colorB)-GetRValue((COLORREF)colorS) > GetRValue((COLORREF)errorcolor))
  240.                                         || abs(GetGValue((COLORREF)colorB)-GetGValue((COLORREF)colorS) > GetGValue((COLORREF)errorcolor))
  241.                                         || abs(GetBValue((COLORREF)colorB)-GetBValue((COLORREF)colorS) > GetBValue((COLORREF)errorcolor)) ){
  242.                                         count++;
  243.                                 }
  244.                         }
  245.                 }
  246.         if(count>errorcount)
  247.                 return 0;
  248.         else
  249.                 return 1;
  250. }

  251. //从矩形x1,y1,x2,y2内查找与位图lpszName条件匹配的起始点
  252. //若有匹配的,(fx,fy)为图片第一次出现的左上角顶点,并返回匹配个数
  253. //忽略位图backcolor颜色点,颜色偏差errorcolor,允许不匹配点的个数errorcount
  254. int FindBmpEx(int x1,int y1,int x2,int y2,LPCTSTR lpszName,int backcolor,int errorcolor,int errorcount,int &fx,int &fy)
  255. {
  256.         int x,y,color=-1;

  257.         GetBmpData(lpszName);
  258.         GetScreenData(x2,y2);
  259.         for(y=0;y<bm.bmHeight-1;y++)
  260.         {
  261.                 for(x=0;x<bm.bmWidth-1;x++)
  262.                         if(GetBmpPixel(x,y)!=errorcount)
  263.                         {
  264.                                 color=GetBmpPixel(x,y);
  265.                                 break;
  266.                         }
  267.                 if(color>0)break;
  268.         }

  269.         Points *head,*tail,*p,*q;
  270.         head=tail=NULL;
  271.         int xtmp=x1,countP=0,countB=0;
  272.         for(;y1<y2;y1++)
  273.                 for(x1=xtmp;x1<=x2;x1++)
  274.                         if(GetScrPixel(x1,y1)==color)
  275.                                 {
  276.                                         countP++;
  277.                                         p=(struct Points *)malloc(sizeof(struct Points));
  278.                                         (p->pts).x=x1-x;
  279.                                         (p->pts).y=y1-y;
  280.                                         if(head==NULL)q=head=tail=p;
  281.                                         else
  282.                                                 tail=tail->next;
  283.                                         tail->next=p;
  284.                                 }
  285.         p->next=NULL;
  286.         while(q)
  287.         {
  288.                 if(CompareEx((q->pts),backcolor,errorcolor,errorcount))
  289.                 {
  290.                         countB++;
  291.                         if(countB==1)
  292.                         {
  293.                                 fx=(q->pts).x;
  294.                                 fy=(q->pts).y;
  295.                         }
  296.                 }
  297.                 p=q->next;
  298.                 free(q);
  299.                 q=p;
  300.         }

  301.         ReleaseLP();
  302.         return countB;

  303. }

复制代码
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-29 18:04

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表