转自:http://blog.sina.com.cn/s/blog_589d32f5010008m9.html
function FindBitmapPoint( //寻找子位图的位置
mBitmapMain: TBitmap; //主位图
mBitmapSub: TBitmap //子位图
): TPoint; //返回子图像存在的坐标,如不存在则返回(-1,-1)
//设计 Zswang 2006-08-04 wjhu111#21cn.com 尊重作者,转贴请注明出处
const
//pfDevice, pf1bit, pf4bit, pf8bit, pf15bit, pf16bit, pf24bit, pf32bit, pfCustom
cBitsPerPixels: array[TPixelFormat] of Byte = (0, 1, 4, 8, 15, 16, 24, 32, 0);
//像素格式所占用的字位数列表
var
I, J, K, L: Integer; //循环变量
vStrMain: string; //主位图一行的像素数据字符串格式
vStrSub: string; //子位图一行的像素数据字符串格式
vLine: PChar; //临时ScanLine用
vBytesSub: Integer; //子位图一行像素数据占用的字节数
vBytesMain: Integer; //主位图一行像素数据占用的字节数
vBitsPerPixels: Byte; //一个像素占用的字位数
vFlag: Boolean;
begin
Result := Point(-1, -1);
///////Begin 安全判断
if not Assigned(mBitmapMain) or not Assigned(mBitmapSub) then Exit;
if mBitmapMain.PixelFormat <> mBitmapSub.PixelFormat then Exit;
if (mBitmapSub.Height <= 0) or (mBitmapSub.Width <= 0) or
(mBitmapMain.Height <= 0) or (mBitmapMain.Width <= 0) then Exit;
///////End 安全判断
vBitsPerPixels := cBitsPerPixels[mBitmapMain.PixelFormat];
if vBitsPerPixels = 0 then Exit;
vBytesSub := (mBitmapSub.Width * vBitsPerPixels + 7) div 8;
vBytesMain := (mBitmapMain.Width * vBitsPerPixels + 7) div 8;
if (vBytesSub = 0) or (vBytesMain = 0) then Exit;
SetLength(vStrSub, vBytesSub);
SetLength(vStrMain, vBytesMain);
vLine := mBitmapSub.ScanLine[0];
Move(vLine^, vStrSub[1], vBytesSub);
for I := 0 to mBitmapMain.Height - 1 do
begin
vLine := mBitmapMain.ScanLine[I];
Move(vLine^, vStrMain[1], vBytesMain);
J := Pos(vStrSub, vStrMain); //寻找子位图第一行是否存在主位图的一行中
L := J;
while J > 0 do
begin
vFlag := True;
for K := 1 to mBitmapSub.Height - 1 do
begin
if I + K >= mBitmapMain.Height then //边界判断
begin
vFlag := False;
Break;
end;
vLine := mBitmapMain.ScanLine[I + K];
Move(vLine^, vStrMain[1], vBytesMain);
vLine := mBitmapSub.ScanLine[K];
Move(vLine^, vStrSub[1], vBytesSub);
if not CompareMem(@vStrSub[1], @vStrMain[J], vBytesSub) then //判断子位图之后的行以相应主位图是否一致
begin
vLine := mBitmapMain.ScanLine[I];
Move(vLine^, vStrMain[1], vBytesMain);
vLine := mBitmapSub.ScanLine[0];
Move(vLine^, vStrSub[1], vBytesSub);
vFlag := False; //不一致打上标记
Break;
end;
end;
if vFlag then //一致则返回
begin
Result := Point((J - 1) div vBitsPerPixels * 8, I);
//计算多少像素位置
Break;
end;
J := Pos(vStrSub, Copy(vStrMain, L + 1, MaxInt)); //考虑子位图第一行在主位图`后面还会出现的情况