1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | //代码可以运行和测试,可以在大图里截几个小图试一下,用简单的黑白图片测试即可(截那个图里的几个小图存到一个路径里做模 //版,Edit1的值指向那个路径,Image1加载大图),24位的bmp格式. unit Main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, ExtDlgs, IdGlobal; const PixelCountMax = 32768 ; type pRGBTripleArray = ^TRGBTripleArray; TRGBTripleArray = array [ 0.. PixelCountMax - 1 ] of TRGBTriple; type TMainForm = class (TForm) Image1: TImage; Image2: TImage; Memo1: TMemo; Button1: TButton; OpenPictureDialog1: TOpenPictureDialog; OpenPictureDialog2: TOpenPictureDialog; Label1: TLabel; Memo2: TMemo; Edit1: TEdit; Button4: TButton; procedure Button1Click(Sender: TObject); procedure FormCreate(Sender: TObject); function BmpCmpEx(bmpBig, bmp: TBitmap; x, y: integer ; nV: byte ): boolean ; //图片对比 function BmpFindEx(bmpBig, bmp: TBitmap; x1, y1, x2, y2: integer ; nV: byte ; Txt: string ): Boolean ; private { Private declarations } public { Public declarations } end ; var MainForm: TMainForm; //L, T, Lx: Integer; //已找到的子图的x和Y值 ,也就是左边和上边 bmpFindX, bmpFindY: Integer ; //第二种方法找到的点 TxtAry: array of string ; eight: array [ 1..8 , 1..8 ] of TLabel; implementation uses StrUtils; { $R *.dfm} //初始化 procedure TMainForm . FormCreate(Sender: TObject); begin DoubleBuffered := True ; Image1 . Picture . Bitmap . PixelFormat := pf24bit; Image2 . Picture . Bitmap . PixelFormat := pf24bit; end ; // 在大图里对比小图 function TMainForm . BmpCmpEx(bmpBig, bmp: TBitmap; x, y: integer ; nV: byte ): boolean ; var i, j: integer ; row1, row2: pRGBTripleArray; p1, p2: TRGBTriple; pLow, pHigh: TRGBTriple; begin result := true ; //扫描整个小图 for j := 0 to bmp . Height - 1 do begin row1 := bmpBig . ScanLine[y + j]; //大图 row2 := bmp . ScanLine[j]; //小图 for i := 0 to bmp . Width - 1 do begin p1 := row1[x + i]; p2 := row2[i]; if not ((p1 . rgbtRed = p2 . rgbtRed) and (p1 . rgbtGreen = p2 . rgbtGreen) and (p1 . rgbtBlue = p2 . rgbtBlue)) then begin result := false ; exit; //不同则退出 end ; end ; end ; end ; // 在大图里的(x1,y1)和(x2,y2)中找出小图来? // 当返回true时,以下变量存放找到的位置 // bmpFindX:integer; // bmpFindY:integer; function TMainForm . BmpFindEx(bmpBig, bmp: TBitmap; x1, y1, x2, y2: integer ; nV: byte ; Txt: string ): Boolean ; var x, y: integer ; begin if x1 + y1 + x2 + y2 = 0 then begin x1 := 0 ; y1 := 0 ; x2 := bmpBig . Width - 1 ; y2 := bmpBig . Height - 1 ; end ; for y := y1 to y2 - 1 do //循环大图的行 begin if bmp . Height > y2 - y then //高度不够,失败了 break; for x := x1 to x2 - 1 do //循环大图的列 begin if (bmp . Width > x2 - x) then //宽度不够,本行完成检查了 break; begin Application . ProcessMessages; if BmpCmpEx(bmpBig, bmp, x, y, nV) then //在每一个大图的点上,对比小图, begin TxtAry[x] := txt; //找到后,把匹配的小图的位置记录到对应的数组中//数组长度本来就是以图片长度为准的 result := true ; bmpFindX := x; bmpFindY := y; end ; end ; // end if end ; // end for x end ; // end for y result := false ; // 到这里就是失败 end ; procedure TMainForm . Button1Click(Sender: TObject); var i, j, k: Integer ; LibDir, LibName: string ; //小图的文件位置和名称 LibStr: TStringList; //把图片长度变成每个点,把检测到图片名字填上去 begin try LibDir := edit1 . Text; //读取小图模版文件列表 LibStr := TStringList . Create; LibStr . LoadFromFile(LibDir + 'Lib.txt' ); SetLength(TxtAry, 0 ); SetLength(TxtAry, Image1 . Picture . Bitmap . Width); // 数组长度等于图片宽度 for i := 0 to LibStr . Count - 1 do //循环所有的小图模版图片 begin Application . ProcessMessages; LibName := LibDir + LibStr . Strings[i] + '.bmp' ; if not FileExists(LibName) then Continue; Image2 . Picture . LoadFromFile(LibName); // 加载小图模版图片 //第二种找图方法 if BmpFindEx(Image1 . Picture . Bitmap, Image2 . Picture . Bitmap, 0 , 0 , Image1 . Picture . Bitmap . Width, Image1 . Picture . Bitmap . Height, 5 , LibStr . Strings[i]) then //LibStr.Strings[i]就是小图的文件名 begin //Memo2.Lines.Add(IntToStr(bmpFindX)+','+IntToStr(bmpFindY)+':'+LibStr.Strings[i]); end ; end ; finally LibStr . Free; end ; Memo1 . Lines . SaveToFile( 'C:\log.txt' ); end ; end . |
联系客服