zoukankan      html  css  js  c++  java
  • Delphi下实现全屏快速找图找色 四、BitmapData.pas的使用

    四、BitmapData.pas的使用
    (注:以上压缩包中的BitmapData.pas文件有个小BGU,主要是截取鼠标指针的图片时没有考虑当前的背景颜色,始终为黑色。在本贴三楼的压缩包中有更新后的BitmapData.pas文件下载。)
      在上面的压缩包中是BitmapData.pas使用的示范程序,BitmapData.pas文件可以从压缩包中获得。在BitmapData.pas文件中我将位图数据封装成了类TBDBitmapData,以便于使用。另外我编写一系列的函数用以BGR格式颜色的构建、转换、模糊比较。注意在BitmapData.pas文件中我定义了一些常量,这些常量只是为了增加程序的可读性,修改这些常量不会修改程序支持数据的格式,只会使程序运行错误。BitmapData.pas文件的详细说明如下:

    1、function BGR(B,G,R : Byte): TBDColor;
      根据蓝(B)、绿(G)、红(R)三个通道的值生成一个BGR格式颜色。

    2、function RGBtoBGR(C : TColor): TBDColor;
      将一个RGB颜色格式转换到BGR颜色格式。

    3、function BGRtoRGB(C : TBDColor): TColor;
      将一个BGR颜色格式转换到RGB颜色格式。

    4、function BDCompareColor(C1,C2 : TBDColor; const Range : TBDColorRange): Boolean;
      根据颜色范围Range比较颜色C1和C2,返回C1和C2是否相似。C1和C2是BGR格式的颜色,Range是颜色的变化范围。

     TBDColorRange的定义如下:
      TBDColorRange = record
        R: Integer;
        G: Integer;
        B: Integer;
      end;
      其中,R表示C1和C2中红色通道最大的相差值;G表示C1和C2中绿色通道最大的相差值;B表示C1和C2中蓝色通道最大的相差值。

      示范程序,比较两个颜色:
    var 
        C1,C2 : TBDColor; 
        Range : TBDColorRange; 
    begin 
        Range.R:=5; 
        Range.G:=5; 
        Range.B:=5;  
        C1:=BGR(125,125,125); 
        C2:=BGR(120,120,120); 
        BDCompareColor(C1,C2,Range); //成功  
        C1:=BGR(125,120,125); 
        C2:=BGR(120,120,120); 
        BDCompareColor(C1,C2,Range); //成功  
        C1:=BGR(125,200,125); 
        C2:=BGR(120,120,120); 
        BDCompareColor(C1,C2,Range); //失败 
    end;

    5、constructor TBDBitmapData.Create(const AName : String);
      新建一个TBDBitmapData对象的实例。可以为实例指定一个名字,便于以后的管理。

    6、procedure TBDBitmapData.Clear;
      清除当前TBDBitmapData对象中加载的位图数据。

    7、function TBDBitmapData.LoadFromStream(Stream : TStream; ABackColor : TBDColor): Boolean;
      从数据流Stream中导入位图数据,返回是否成功。如果失败将设置Error成员说明情况。数据流中的数据必需是24位BMP格式文件数据。利用ABackColor可以设定图片的背景颜色,该参数可以省略,省略时表示图片不使用背景颜色。

    8、function TBDBitmapData.SaveToStream(Stream : TStream):Boolean;
      将当前加载的位图数据导出到数据流Stream中,返回是否成功。如果失败将设置Error成员说明情况。数据将按24位BMP文件数据格式导出到数据流中。

    9、function TBDBitmapData.LoadFromFile(const FileName : string; ABackColor : TBDColor): Boolean;
      从文件FileName中导入位图数据,返回是否成功。如果失败将设置Error成员说明情况。文件必需是24位BMP格式文件。利用ABackColor可以设定图片的背景颜色,该参数可以省略,省略时表示图片不使用背景颜色。

    10、function TBDBitmapData.SaveToFile(const FileName : string): Boolean;
      将当前加载的位图数据导出到文件中,返回是否成功。如果失败将设置Error成员说明情况。数据按24位BMP文件数据格式导出到文件中。

    11、function TBDBitmapData.LoadFromBitmap(Bitmap : TBitmap): Boolean;
      从一个TBitmap对象中导入数据,返回是否成功。如果失败将设置Error成员说明情况。导入时图片的背景颜色由Bitmap.Transparent和Bitmap.TransparentColor决定。

    12、function TBDBitmapData.SaveToBitmap(Bitmap : TBitmap): Boolean;
      将当前的位图数据导出到一个TBitmap对象中,返回是否成功。如果失败将设置Error成员说明情况。导出时将根据当前的背景颜色设置Bitmap.Transparent和Bitmap.TransparentColor成员。利用LoadFromBitmap和SaveToBitmap两个函数可以实现TBDBitmapData对象和TBitmap对象的相互转换。

    13、function TBDBitmapData.CopyFormScreen(Left,Top,AWidth,AHeight : Integer): Boolean;
      从屏幕上的指定范围中截图,并导入数据,返回是否成功。如果失败将设置Error成员说明情况。Left为截图的左边距,可省略,默认为0;Top为截图的顶边距,可省略,默认为0;AWidth为截图的宽度,可省略,默认为从Left到屏幕右边的宽度;AHeight为截图的高度,可省略,默认为从Top到屏幕底边的高度。

    14、function TBDBitmapData.CopyFormCursor: Boolean;
      截取鼠标当前指针的图片,并导入数据,返回是否成功。如果失败将设置Error成员说明情况。如果鼠标指针是动画指针,默认截取第一帧画面。截取时会使用当前背景颜色填充背景,如果没有指定背景颜色则使用白色(RGB(255,255,255))填充。

    15、function TBDBitmapData.Compare(Bmp : TBDBitmapData; Left,Top : Integer): Boolean;
    16、function TBDBitmapData.Compare(Bmp : TBDBitmapData; const Range : TBDColorRange; Left,Top : Integer): Boolean;
      重载的两个函数,用于在当前位图的指定位置比较Bmp指定的位图,返回是否一致。无论比较是否一致都不会修改Error成员。第一个函数用于精确比较,第二个函数用于模糊比较。Bmp指定的位图面幅要小于等于当前位图的面幅,Bmp指定的位图不能超出当前位图,否则比较失败。Bmp为指定的位图数据;Left为比较时的左边距,可省略,默认为0;Top为比较时的顶边距,可省略,默认为0;Range为颜色变化范围。

    17、function TBDBitmapData.FindImage(Bmp : TBDBitmapData; var Left,Top : Integer): Boolean;
    18、function TBDBitmapData.FindImage(Bmp : TBDBitmapData; const Range : TBDColorRange; var Left,Top : Integer): Boolean;
      重载的两个函数,从当前位图中查找与Bmp一致的子图,返回是否找到。无论是否找到都不会修改Error成员。第一个函数用于精确比较,第二个函数用于模糊比较。查找时忽略Left和Top的设置,从当前位图的左上角开始按从左到右,从上到下的顺序查找。找到返回true,设置Left和Top为找到子图的位置;没找到返回false,设置Left和Top为-1。Bmp为指定的子图数据;Left为找到子图的左边距;Top为找到子图的顶边距;Range为颜色变化范围。

      示范程序,在屏幕上查找子图:

    var 
        Bit1,Bit2 : TBDBitmapData; 
        Left,Top : Integer
    begin 
        Bit1:=TBDBitmapData.Create; 
        Bit2:=TBDBitmapData.Create; 
     
        Bit1.CopyFormScreen; 
        Bit2.LoadFromFile('文件名'); 
     
        if Bit1.FindImage(Bit2,Left,Top) then 
        begin 
            {已找到子图,进行相应的处理...} 
        end; 
     
        Bit1.Free; 
        Bit2.Free; 
    end;

    19、function TBDBitmapData.FindCenterImage(Bmp : TBDBitmapData; var Left,Top : Integer): Boolean;
    20、function TBDBitmapData.FindCenterImage(Bmp : TBDBitmapData; const Range : TBDColorRange; var Left,Top : Integer): Boolean;
      重载的两个函数,从当前位图中查找与Bmp一致的子图,返回是否找到。无论是否找到都不会修改Error成员。第一个函数用于精确比较,第二个函数用于模糊比较。查找时以Left和Top的设置为基点,从中心向四周查找。找到返回true,设置Left和Top为找到子图的位置;没找到返回false,设置Left和Top为-1。Bmp为指定的子图数据;Left为找到子图的左边距;Top为找到子图的顶边距;Range为颜色变化范围。

    21、function TBDBitmapData.EnumImage(Bmp : TBDBitmapData; EnumImageProc : TBDEnumImageProc; lParam : Integer): Boolean;
    22、function TBDBitmapData.EnumImage(Bmp : TBDBitmapData; const Range : TBDColorRange; EnumImageProc : TBDEnumImageProc; lParam : Integer): Boolean;
      重载的两个函数,从当前位图中查找所有与Bmp一致的子图,即枚举位图,返回是否找到。无论是否找到都不会修改Error成员。第一个函数用于精确比较,第二个函数用于模糊比较。查找时从当前位图的左上角开始按从左到右,从上到下的顺序查找。每当查找到一个子图,就调用回调函数EnumImageProc,如果EnumImageProc返回false就停止查找,结束函数。Bmp为子图数据;EnumImageProc为回调函数;lParam为调用回调函数时发出的参数,可省略,默认为0;Range为颜色变化范围。TBDEnumImageProc的声明格式如下:

    TBDEnumImageProc = function (Left,Top : Integer; Bmp : TBDBitmapData; lParam : Integer): Boolean;

      其中,Left为找到子图的左边距;Top为找到子图的顶边距;Bmp为调用EnumImage时给出的查找子图数据;lParam为调用EnumImage时给出的设置参数。该函数的返回值表示是否继续枚举。

    23、function TBDBitmapData.FindColor(Color : TBDColor; var Left,Top : Integer): Boolean;
    24、function TBDBitmapData.FindColor(Color : TBDColor; const Range : TBDColorRange; var Left,Top :Integer): Boolean;
      重载的两个函数,从当前位图中查找指定的颜色,忽略当前位图背景颜色BackColor的设置,返回是否找到。无论是否找到都不会修改Error成员。第一个函数用于精确比较,第二个函数用于模糊比较。查找时忽略Left和Top的设置,从当前位图的左上角开始按从左到右,从上到下的顺序查找。找到返回true,设置Left和Top为找到颜色的位置,没找到返回false,设置Left和Top为-1。Color为BGR格式颜色;Left为找到颜色的左边距;Top为找到颜色的顶边距;Range为颜色变化范围。

    25、function TBDBitmapData.FindCenterColor(Color : TBDColor; var Left,Top : Integer): Boolean;

    26、function TBDBitmapData.FindCenterColor(Color : TBDColor; const Range : TBDColorRange; var Left,Top : Integer): Boolean;

      重载的两个函数,从当前位图中查找指定的颜色,忽略当前位图背景颜色BackColor的设置,返回是否找到。无论是否找到都不会修改Error成员。第一个函数用于精确比较,第二个函数用于模糊比较。查找时以Left和Top的设置为基点,从中心向四周查找。找到返回true,设置Left和Top为找到颜色的位置,没找到返回false,设置Left和Top为-1。Color为BGR格式颜色;Left为找到颜色的左边距;Top为找到颜色的顶边距;Range为颜色变化范围。

      示范程序,在屏幕上以某点为中心向四周模糊查找颜色:
    var 
        Bit : TBDBitmapData; 
        Range : TBDColorRange; 
        Left,Top : Integer
    begin 
        Bit:=TBDBitmapData.Create; 
        Bit.CopyFormScreen; 
     
        Range.R:=5; 
        Range.G:=5; 
        Range.B:=5; 
     
        Left:=600; 
        Top:=380; 
     
        if Bit.FindCenterColor(BGR(0,250,250),Range,Left,Top) then 
        begin 
            {已找到颜色,进行相应的处理...} 
        end; 
     
        Bit.Free; 
    end;

    27、function TBDBitmapData.EnumColor(Color : TBDColor; EnumColorProc : TBDEnumColorProc; lParam : Integer): Boolean;
    28、function TBDBitmapData.EnumColor(Color : TBDColor; const Range : TBDColorRange; EnumColorProc : TBDEnumColorProc; lParam : Integer): Boolean;
      重载的两个函数,从当前图片中查找所有指定的颜色,即枚举颜色,忽略当前位图背景颜色BackColor的设置,返回是否找到。无论是否找到都不会修改Error成员。第一个函数用于精确比较,第二个函数用于模糊比较。查找时从当前位图的左上角开始按从左到右,从上到下的顺序查找。每找到一个颜色,就调用回调函数EnumColorProc,如果EnumColorProc返回false就停止查找,结束函数。Color为BGR格式颜色;EnumColorProc为回调函数;lParam为调用回调函数时发出的参数,可省略,默认为0;Range为颜色变化范围。TBDEnumColorProc的声明格式如下:

    TBDEnumColorProc = function (Left,Top : Integer; Color : TBDColor; lParam : Integer): Boolean;

      其中,Left为找到颜色的左边距;Top为找到颜色的顶边距;Color为找到的颜色,当使用模糊查找时该颜色为实际找到的颜色;lParam为调用EnumColor时给出的设置参数。该函数的返回值表示是否继续枚举。

    29、TBDBitmapData.Error
      最近一次操作出现的错误的说明。出于性能方面的考虑,只有导入、导出、截图等操作才会修改这个成员。而查找、枚举等操作无论是否成功都不会修改这个成员。

    30、TBDBitmapData.Name
      当前位图的名称,可读写。方便位图数据的管理。

    31、TBDBitmapData.Width
      当前位图宽度,以象素为单位,只读。

    32、TBDBitmapData.Height
      当前位图高度,以象素为单位,只读。

    33、TBDBitmapData.BackColor
      当前位图的背景颜色,BGR格式的颜色,可读写。当该颜色为BD_COLORLESS时,表示该位图不使用背景颜色。

    34、TBDBitmapData.LineWidth
      对齐后每行位图数据的宽度,以字节为单位,只读。

    35、TBDBitmapData.SpareWidth
      对齐后每行位图数据填充的多余宽度,以字节为单位,只读。

    36、TBDBitmapData.Size
      位图数据的长度,以字节为单位,只读。

    37、TBDBitmapData.Bits
      位图数据缓冲区指针,只读。这个指针是只读的,但它指向的数据是可读写的。可以将这个属性看成是一个一维的字节数组,可以对缓冲区中的数据进行访问和修改。

    38、TBDBitmapData.Pixels[Left,Top : Integer]
      位图的象素颜色,BGR格式的颜色,可读写。利用这个属性可以将位图看成是一个二维的象素矩阵,可以对矩阵中的象素颜色进行访问和修改。

      示范代码,位图数据的访问:
    var 
        Bit : TBDBitmapData; 
    begin 
        Bit:=TBDBitmapData.Create; 
        Bit.CopyFormScreen; 
     
        Bit.Bits[50]; //以Byte格式访问 
     
        Bit.Pixels[10,10]; //以BGR颜色格式访问 
     
        Bit[10,10]; //等同于Bit.Pixels[10,10]; 
     
        Bit.Free; 
    end; 

    利用TBDBitmapData对象查找两张图片上的不同,从右上角开始利用双层循环遍历两图上的所有象素点,并相互比较。不完整代码如下:

    procedure TForm1.Button5Click(Sender: TObject);
    var
        Bmp1,Bmp2 : TBDBitmapData;
        Left,Top : Integer;
        IsExit : Boolean;
    begin
        Bmp1:=TBDBitmapData.Create;
        Bmp2:=TBDBitmapData.Create;

        Bmp1.LoadFromFile('文件名1');
        Bmp2.LoadFromFile('文件名2');

        //假设两张图片一样大

        IsExit:=false;
        for Top:=0 to Bmp1.Height-1 do
        begin
            for Left:=0 to Bmp1.Width-1 do
            begin
                if Bmp1[Left,Top]<>Bmp2[Left,Top] then
                begin
                    //在(Left,Top)位置两张图片有不同

                    //相应的处理...

                    if {如果不继续查找其它不同} then
                    begin
                        IsExit:=true; //用以退出循环
                        break;
                    end;
                end;
            end;
            if IsExit then break;
        end;

        Bmp1.Free;
        Bmp2.Free;
    end;

    以上代码不完整,可以根据需要进行修改。

  • 相关阅读:
    关于hql执行带有case when 的语句问题,另:数据表的倒置
    xslt 转换 xml
    xsd校验xml
    java 调用存储过程
    js return无效,表单自动提交
    bat 启动java程序
    Delphi 窗体拖动,无边框,透明的设置
    installshield实例(三)发布,补丁,升级
    Installshield实例(二)创建自定义界面
    InstallShield 实例(一)检测JDK,MYSQL,创建数据库
  • 原文地址:https://www.cnblogs.com/MaxWoods/p/3135374.html
Copyright © 2011-2022 走看看