AutoHotkey的源码,模糊找图和精确找图思路一样,也是用笨方法。原来的C代码比较难看懂,这里的delphi代码,很容易弄明白。
以下是模糊的找图。如果需要,可以再做优化处理。注意我这里去掉了透明处理,需要的自己加上吧。
因为用到了iif函数,别忘了uses IdGlobal;
//
模糊判断,在大图里的(x,y)位置上是不是小图?
// 其中nV是R,G,B的偏差值, 0 .. 255
function BmpCmpEx(bmpBig,bmp:TBitmap;x,y:integer;nV:byte):boolean;
var
i,j:integer;
row1, row2:pRGBTripArray;
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];
// uses IdGlobal, 如果使用IfThen代替iif, Uses Math
pLow.rgbtRed : = iif(nV > p2.rgbtRed, 0 , p2.rgbtRed - nV);
pLow.rgbtGreen : = iif(nV > p2.rgbtGreen, 0 , p2.rgbtGreen - nV);
pLow.rgbtBlue : = iif(nV > p2.rgbtBlue , 0 , p2.rgbtBlue - nV);
pHigh.rgbtRed : = iif((nV > $FF - p2.rgbtRed) , $FF , p2.rgbtRed + nV);
pHigh.rgbtGreen : = iif((nV > $FF - p2.rgbtGreen) , $FF , p2.rgbtGreen + nV);
pHigh.rgbtBlue : = iif((nV > $FF - p2.rgbtBlue) , $FF , p2.rgbtBlue + nV);
if not ((p1.rgbtRed >= pLow.rgbtRed) and (p1.rgbtRed <= pHigh.rgbtRed)
and (p1.rgbtGreen >= pLow.rgbtGreen) and (p1.rgbtGreen <= pHigh.rgbtGreen)
and (p1.rgbtBlue >= pLow.rgbtBlue) and (p1.rgbtBlue <= pHigh.rgbtBlue)) then
begin
result: = false;
exit;
end ;
end ;
end ;
end ;
// 其中nV是R,G,B的偏差值, 0 .. 255
function BmpCmpEx(bmpBig,bmp:TBitmap;x,y:integer;nV:byte):boolean;
var
i,j:integer;
row1, row2:pRGBTripArray;
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];
// uses IdGlobal, 如果使用IfThen代替iif, Uses Math
pLow.rgbtRed : = iif(nV > p2.rgbtRed, 0 , p2.rgbtRed - nV);
pLow.rgbtGreen : = iif(nV > p2.rgbtGreen, 0 , p2.rgbtGreen - nV);
pLow.rgbtBlue : = iif(nV > p2.rgbtBlue , 0 , p2.rgbtBlue - nV);
pHigh.rgbtRed : = iif((nV > $FF - p2.rgbtRed) , $FF , p2.rgbtRed + nV);
pHigh.rgbtGreen : = iif((nV > $FF - p2.rgbtGreen) , $FF , p2.rgbtGreen + nV);
pHigh.rgbtBlue : = iif((nV > $FF - p2.rgbtBlue) , $FF , p2.rgbtBlue + nV);
if not ((p1.rgbtRed >= pLow.rgbtRed) and (p1.rgbtRed <= pHigh.rgbtRed)
and (p1.rgbtGreen >= pLow.rgbtGreen) and (p1.rgbtGreen <= pHigh.rgbtGreen)
and (p1.rgbtBlue >= pLow.rgbtBlue) and (p1.rgbtBlue <= pHigh.rgbtBlue)) then
begin
result: = false;
exit;
end ;
end ;
end ;
end ;
以下是模糊找图, 调用模糊判断
//
模糊找图,在大图里的(x1,y1)和(x2,y2)中找出小图来?
// 其中nV是R,G,B的偏差值, 0 .. 255
// 当返回true时,以下变量存放找到的位置
// bmpFindX:integer;
// bmpFindY:integer;
function BmpFindEx(bmpBig,bmp:TBitmap;x1,y1,x2,y2:integer;nV:byte):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
if BmpCmpEx(bmpBig,bmp,x,y,nV) then
begin
result: = true;
bmpFindX: = x;
bmpFindY: = y;
exit;
end ;
end ; // end if
end ; // end for x
end ; // end for y
result: = false; // 到这里就是失败
end ;
// 其中nV是R,G,B的偏差值, 0 .. 255
// 当返回true时,以下变量存放找到的位置
// bmpFindX:integer;
// bmpFindY:integer;
function BmpFindEx(bmpBig,bmp:TBitmap;x1,y1,x2,y2:integer;nV:byte):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
if BmpCmpEx(bmpBig,bmp,x,y,nV) then
begin
result: = true;
bmpFindX: = x;
bmpFindY: = y;
exit;
end ;
end ; // end if
end ; // end for x
end ; // end for y
result: = false; // 到这里就是失败
end ;