@BlueStarHH:
Ich hab da mal auf die Schnelle was zusammengefrickelt.
Die Funktion FindDeltaRect liefert das Rechteck, in dem sich die Bilder unterscheiden.
Wenn die Bilder gleich sind, wird ein leeres Rechteck zurückgegeben.
Zum Test hab ich
1) Ein Bild mit 4928 x 3264 Pixeln als 24Bit Bitmap unter "A.bmp" gespeichert.
2) In das Bild einen kleinen Kreis gezeichnet und unter "B.bmp" gespeichert.
3) Die unten gezeigte Testprozedur laufen lassen.
Ausgegeben wurde
Code:
Bmp-Size: 4928 x 3264
A vs A, T: 47 ms, R: 0 0 0 0
A vs B, T: 47 ms, R: 1005 442 1035 464
Also 47 ms für Bilder mit 16 MPixeln.
Delphi-Quellcode:
FUNCTION FindDeltaRect(A,B:TBitmap):TRect;
var W,H,LO,X,Y:NativeInt; PA,PB,P1,P2:PByte;
begin
W:=A.Width;
H:=A.Height;
if W<>B.Width
then raise Exception.Create('
Unterschiedliche Breiten');
if H<>B.Height
then raise Exception.Create('
Unterschiedliche Höhen');
if A.PixelFormat<>pf24bit
then raise Exception.Create('
A ist micht pf24bit');
if B.PixelFormat<>pf24bit
then raise Exception.Create('
B ist micht pf24bit');
if (W=0)
or (H=0)
then raise Exception.Create('
Bitmaps sind leer');
PA:=A.ScanLine[0];
LO:=NativeInt(A.ScanLine[1])-NativeInt(PA);
PB:=B.ScanLine[0];
SetRect(Result,MaxInt,MaxInt,-MaxInt,-MaxInt);
for Y:=0
to H-1
do begin
P1:=PA;
P2:=PB;
for X:=0
to W-1
do begin
if (PWord(P1)^<>PWord(P2)^)
or ((P1+2)^<>(P2+2)^)
then begin
with Result
do begin
if X<Left
then Left:=X;
if X>Right
then Right:=X;
if Y<Top
then Top:=Y;
if Y>Bottom
then Bottom:=Y;
end;
end;
Inc(P1,3);
Inc(P2,3);
end;
Inc(PA,LO);
Inc(PB,LO);
end;
if Result.Left=MaxInt
then begin
SetRect(Result,0,0,0,0);
end else begin
Inc(Result.Right);
Inc(Result.Bottom);
end;
end;
Testprozedur:
Delphi-Quellcode:
PROCEDURE TMain.Test;
var A,B:TBitmap; R1,R2:TRect; T1,T2:Cardinal;
begin
A:=Nil;
B:=Nil;
try
try
A:=TBitmap.Create;
B:=TBitmap.Create;
A.LoadFromFile(ExtractFilePath(ParamStr(0))+'
A.Bmp');
B.LoadFromFile(ExtractFilePath(ParamStr(0))+'
B.Bmp');
T1:=GetTickCount;
R1:=FindDeltaRect(A,A);
T1:=GetTickCount-T1;
T2:=GetTickCount;
R2:=FindDeltaRect(A,B);
T2:=GetTickCount-T2;
ShowMessage('
Bmp-Size: '+IntToStr(A.Width)+'
x '+IntToStr(A.Height)+#13+
'
A vs A, T: '+IntToStr(T1)+'
ms, R: '+
IntToStr(R1.Left)+'
'+IntToStr(R1.Top)+'
'+
IntToStr(R1.Right)+'
'+IntToStr(R1.Bottom)+#13+
'
A vs B, T: '+IntToStr(T2)+'
ms, R: '+
IntToStr(R2.Left)+'
'+IntToStr(R2.Top)+'
'+
IntToStr(R2.Right)+'
'+IntToStr(R2.Bottom));
except
on E:
Exception do ShowMessage(E.
Message);
end;
finally
A.Free;
B.Free;
end;
end;