首页
社区
课程
招聘
[求助]如何高速扫描屏幕上的点
发表于: 2007-3-5 13:32 5664

[求助]如何高速扫描屏幕上的点

2007-3-5 13:32
5664
比如,我想找到屏幕上某一颜色值为2881ff的点应该怎么做呢,有一种笨方法是从(0,0)到(1027,768)一个个读取值,不过这样太慢了,慢到程序没有响应。

测试过按键精灵里关于在屏幕上找指定颜色的函数,速度超快,即使在(0,0)到(1027,768)范围内查找,用时也仅为0.09秒左右。不明其理。

希望大家指点一二。

问题二:关于如何在屏幕上查找指定的图形?

我试了get hdc后用getpixel遍历,但这样太慢了,如果是在0,0 1023 768的范围里找,程序会失去响应很长时间.

以下是我的实现,不过用不了,太慢了
// FindColorEx(区域左边:整数,区域上边:整数,区域右边:整数,区域下边:整数,颜色:字符串,整数:0-从左上往右下;1-从中心找;2-从右下往左上,相似度:0.3到1之间,1为精确匹配,输出找到的x坐标:整型变量,输出找到的y坐标:整型变量)

//查找屏幕指定区域内的颜色
procedure TForm1.FindColorEx(Left:integer; Top:integer;Right:integer;Down:integer;Color:Dword;FangXiang:integer;Likes:Real;x:integer;y:integer);
var
DC: HDC;
clr: COLORREF;
i,j,fu,z,k,Cishu:integer;
tem:Dword;
//founed:Boolean;

begin
//清除结果,如果成功找到了,则x,y为该颜色的坐标
  x:=0;
  y:=0;
  //founed:=False;
  //0-从左往右;1-从中心找;2-从上往下
DC := GetDC(HWND(nil));
case FangXiang of
   0:begin
       for i:=Top to Down do
          begin
          for j:=Left to Right do
            begin
            clr := GetPixel(DC,j,i);
            tem:=ColorToRGB(clr)-Color;
            if Likes=1 then
                begin
                 if tem=0  then
                   begin
                    x:=j;
                    y:=i;
                    //添加找到后的操作
                    break;
                   end;
                end
             else
                begin

                   if (tem>=-300) and (tem<= 300)  then
                   begin
                    x:=j;
                    y:=i;
                    //添加找到后的操作
                    break;
                   end;
                end;
            if (x>0) and (y>0) then break;
            end;
          if (x>0) and (y>0) then break;
          end;
     end;

   1:begin
       fu:=1;
       Cishu:=Round((Down-Top)/2);
       //i=1;
      // while i<Cishu do
         for i:=1 to Cishu do
             begin
             for j:=Cishu+Top to Down do
                 begin
                 for z:=1 to 2 do
                     begin
                     for k:=Left to Right do
                         begin
                           clr := GetPixel(DC,k,j+i*fu);
                           tem:=ColorToRGB(clr)-Color;
                           {if (tem>=-300) and (tem<= 300)  then
                              begin
                               x:=j;
                               y:=i;
                              //添加找到后的操作

                              end; }
                           if Likes=1 then
                              begin
                              if tem=0  then
                                 begin
                                 x:=j;
                                 y:=i;
                               //添加找到后的操作
                                 break;
                                 end;
                              end
                          else
                            begin

                            if (tem>=-300) and (tem<= 300)  then
                               begin
                               x:=j;
                               y:=i;
                               //添加找到后的操作
                               break;
                               end;
                            end;
                           fu:=fu*(-1);
                           if (x>0) and (y>0) then break;
                         end;
                      if (x>0) and (y>0) then break;
                     end;
                 if (x>0) and (y>0) then break;
                end;
             if (x>0) and (y>0) then break;
            end;
     end;
     
   2:begin
        for i:=Left to Right do
          begin
          for j:=Top to Down do
             begin
              clr := GetPixel(DC,j,i);

              tem:=ColorToRGB(clr)-Color;
              {
              if (tem>=-300) and (tem<= 300)  then
                 begin
                  x:=j;
                  y:=i;
                  //添加找到后的操作

                 end;  }
             if Likes=1 then
                begin
                 if tem=0  then
                   begin
                    x:=j;
                    y:=i;
                    //添加找到后的操作
                    break;
                   end;
                end
             else
                begin

                   if (tem>=-300) and (tem<= 300)  then
                   begin
                    x:=j;
                    y:=i;
                    //添加找到后的操作
                    break;
                   end;
               end;

             end;
          if (x>0) and (y>0) then break;
          end;
     end;

   

    end;
end;

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 196
活跃值: (96)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
2
把屏幕信息拷到数组里处理,要快很多

1.截下整个屏幕生成内存bitmap
2.把内存bitmap的颜色信息拿出来放到颜色数组colorData[]
   这里有2种方法:
      1. 用GDI的GetDIBits
      2. 用GDI+的LockBits
3.在colorData里查找你要的颜色
2007-3-5 15:45
0
雪    币: 301
活跃值: (300)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
3
3Q,回我去试试.

一个新问题.我已经通过键盘钩子做了对相应按键的处理(自定义的热键).
问题是,当前进程如果一直在某个timer事件中没有出来的话。即使我按下了停止的热键,程序也不能马上停止。要不停的按,才能让它停下来。
有什么好方法解决吗?
2007-3-6 10:39
0
雪    币: 116
活跃值: (220)
能力值: ( LV12,RANK:370 )
在线值:
发帖
回帖
粉丝
4
在timer事件中作个退出标志,检查这个标志,如果标志置位则退出
2007-3-6 10:43
0
雪    币: 101
活跃值: (12)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
5
主要跟你的代码有关.

可以写个log记录下你的时间.
一般一次大运算需要分解成循环运算,然后在循环中判断标志.
以便能让程序在很段的时间响应.
2007-3-6 10:53
0
雪    币: 196
活跃值: (96)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
6
bool flag = false;

case WM_HOTKEY:
    flag = !flag;
  return 0;
case WM_TIMER:
  if(flag) {
    这里运行时间太长会导致程序没响应
    可以建一个线程
  } else {
    if(线程在运行) {
      结束线程
    }
  }
2007-3-6 12:02
0
雪    币: 301
活跃值: (300)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
7
谢谢各位兄弟
第二个问题已经解决了。用的是创建的新线程。
不过第一个问题还没有完全自己解决,努力中....


to : xIkUg
我试过加标志在程序中判断的方式,但测试后发现。程序应该是没有响应的我按键。还是只能等到循环结束,最后创建了一个新线程。效果不错。
2007-3-10 14:39
0
游客
登录 | 注册 方可回帖
返回
//