Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi zwei Bitmaps vergleichen (https://www.delphipraxis.net/147071-zwei-bitmaps-vergleichen.html)

KahPee 2. Feb 2010 11:32

Re: zwei Bitmaps vergleichen
 
Wo fehlt da noch ein inc() :? ? Ich hätte gesagt, dass die nachfolgende Version eigentlich klappen müsste.. Allerdings ist das nur die Version wo die bei meinem letzten Post angegeben Verbesserungsvorschläge eingearbeitet werden.
Delphi-Quellcode:
function Bitmapcompare(pic1, pic2: Tbitmap; Posx,posy: Integer): Boolean;
var
  Pix1, Pix2   : PByte;
  y, k, x : Integer;
  bytes: Byte;
const
  PixelFormatBytes: Array[TPixelFormat] of Byte = ( 0, 0, 0, 1, 0, 2, 3, 4, 0 );
begin
  result:=false;
  bytes := PixelFormatBytes[pic1.PixelFormat];
  if bytes <> PixelFormatBytes[pic2.PixelFormat] then
    Exit;
  if (bytes = 0) then
    Exit; // PixelFormat wird nicht unterstützt ... kannst du dann gerne von mir aus umändern ...
  if (pic1.Width < pic2.Width) or (pic1.Height < pic2.Height) then
    Exit;
  for y := 0 to pic2.Height - 1 do
  begin
    Pix1 := pic1.Scanline[posy+y];
    Pix2 := pic2.Scanline[y];
    inc(Pix1, Posx*bytes ); //Verschieben der Zeigerposition beim größeren Bild
   
    for x := 0 to pic2.Width - 1 do
      for k := 0 to bytes - 1 do
      begin
    //VERGLEICH
        if pix1^ <> pix2^ then
          Exit;  // ungleich, verlasse deshalb routine. Result ist in diesem Falle = False ...
        inc(Pix1);
        inc(pix2);
      end;
  end;
  // wenn wir es bis hierher geschafft haben, dann sind die bilder von (posx, posy) aufwärts gleich
  Result := true;
end;

Amateurprofi 2. Feb 2010 16:17

Re: zwei Bitmaps vergleichen
 
Scheint zu funktionieren, jedoch hätte ich noch einen Vorschlag, wie das ohne große Mühe, deutlich schneller läuft.
Beim Vergleichen einer Zeile zählst du die Pixel (in x), dann zählst du die Bytes je Pixel (in k).

Ich hole mir die Länge einer Zeile in Bytes.
Hieraus errechne ich die Anzahl der vollen DWords und die ggfs. verbleibenden Bytes.
Beim Prüfen einer Zeile muß ich dann nicht Byte für Byte vergleichen sondern je 4 Bytes auf einmal, was einen entsprechenden Performancegewinn ergibt.
Ich denke, mit etwas Aufwand kann man die Performance noch einmal um 50 bis 100 % steigern.

Delphi-Quellcode:
function xBitmapcompare(pic1, pic2: Tbitmap; Posx,posy: Integer): Boolean;
var
  Pix1, Pix2   : PByte;
  y, k, x, b, dw : Integer;
  bytes: Byte;
const
  PixelFormatBytes: Array[TPixelFormat] of Byte = ( 0, 0, 0, 1, 0, 2, 3, 4, 0 );
begin
  result:=false;
  bytes := PixelFormatBytes[pic1.PixelFormat];
  if bytes <> PixelFormatBytes[pic2.PixelFormat] then
    Exit;
  if (bytes = 0) then
    Exit; // PixelFormat wird nicht unterstützt ... kannst du dann gerne von mir aus umändern ...
  if (pic1.Width < pic2.Width) or (pic1.Height < pic2.Height) then
    Exit;
  b:=bytes*pic2.Width; // Anzahl Bytes je Zeile
  dw:=b shr 2-1;      // Anzahl DWords je zeile
  b:=b and 3-1;       // restliche Bytes je Zeile
  for y := 0 to pic2.Height - 1 do
  begin
    Pix1 := pic1.Scanline[posy+y];
    Pix2 := pic2.Scanline[y];
    inc(Pix1, Posx*bytes ); //Verschieben der Zeigerposition beim größeren Bild
    for x:=dw downto 0 do begin // Volle DWords vergleichen
      if PInteger(Pix1)^ <> PInteger(Pix2)^ then exit;
      inc(Pix1,4);
      inc(pix2,4);
    end;
    for x:=b downto 0 do begin // Restliche Bytes vergleichen
      if Pix1^ <> Pix2^ then exit;
      inc(Pix1);
      inc(pix2);
    end;
  end;
  // wenn wir es bis hierher geschafft haben, dann sind die bilder von (posx, posy) aufwärts gleich
  Result := true;
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:42 Uhr.
Seite 3 von 3     123   

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz