看流星社区-最新易语言安卓C/C++驱动辅助技术分享社区

 找回密码
 注册账号
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
零基础辅助入门教学 原创 高清 专业课程售后(每日解答)
赞助广告位 请点击这里联系站长 QQ20209081
赞助广告位 请点击这里联系站长 QQ20209081
赞助广告位 请点击这里联系站长 QQ20209081
查看: 334|回复: 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, 2019-9-17 08:42

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

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