Einzelnen Beitrag anzeigen

Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.041 Beiträge
 
Delphi XE2 Professional
 
#7

AW: Unterschiede in 2 Bitmaps ermitteln

  Alt 24. Apr 2020, 15:54
@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;
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat