Delphi-PRAXiS
Seite 1 von 3  1 23      

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 1. Feb 2010 13:00


zwei Bitmaps vergleichen
 
Hallo,
ich hatte so eine ähnliche Frage schon mal gestellt, allerdings bin ich bei der Umsetzung damals gescheitert.
Ich habe vor zwei Bitmaps zu vergleichen.
Ich hatte bei meinem ersten Versuch vorallem Probleme mit den konvertieren und ähnlichem. Aber nochmal zu dem Problem:
1. Die beiden Bitmaps haben unterschiedliche größen (Bild1 ist sowohl in y als auch in x Richtung "größer gleich" Bild2)
2. Es soll geprüft werden ob Bild 2 an einer bestimmten Stelle von Bild1 ist
3. Ergebnis soll true/false sein

Im Prinzip stelle ich mir also so etwas vor:
Delphi-Quellcode:
function compareBitmaps(Bild1, Bild2: TBitmap; posx,posy: Integer):boolean;
  //Posx und Posy sollen angeben an welcher Stellen von Bild1 Bild2 verglichen werden wollen (obere linke Ecke)
var x,
    y,
    comparedpix,             //Anzahl der verglichenen Pixel
    machtingpix: integer;    //Anzahl der übereinstimmenden Pixel
   
begin
  Result:=false;

  for x:=0 to Bild2.width-1 do
  begin
    for y:=0 to Bild2.height-1 do
    begin
      if Bild1.Pixels[posx+x,posy+y]=Bild2.Pixels[x,y] then matchingpix:=matchingpix+1;
             //Problem: keine "Pixels" Option für Tbitmaps nur für TCanvas
      comparedpix:=comparedpix+1;
    end;
  end;
 
  if comparedpix=matchingpix then result:=true;

end
Ich hoffe obiger Sketch des Programmcodes kann einen Eindruck vermitteln was ich vor habe. Ich suche auch immer noch eine etwas schnellere Methode. Scanline fällt in diesem Fall weg (???) weil ich ja nur einen Auschnitt vergleichen will.

Wäre nett wenn mir jemand auf die Sprünge helfen könnte ;)

mfg Kahpee

thepaine91 1. Feb 2010 13:08

Re: zwei Bitmaps vergleichen
 
Nein Scanline ist genau richtig. Tipp: Schau dir mal das Return Value an. ;)
Das Beispiel in der Delphi Hilfe zu Scanline kann dir auch weiterhelfen.

KahPee 1. Feb 2010 13:26

Re: zwei Bitmaps vergleichen
 
In meiner Hilfe (TurboDelphi "f1") sieht das seeehr mager aus.
Zitat:

Syntax
Delphi-Quellcode:
 property ScanLine: Pointer read GetScanline;
Beschreibung
ScanLine wird nur bei DIBs (Device Independent Bitmaps) für Bildbearbeitungsprogramme verwendet, die Low-Level-Operationen auf Pixelebene durchführen.
Da komm ich nicht mit weiter. :(
Hast du vllt einen Link oder so? Auch ist mir noch nicht unklar wie ich bei ScanLine einen bestimmten Punkt in Bild1 angebe ab dem verglichen werden soll ...

thepaine91 1. Feb 2010 13:33

Re: zwei Bitmaps vergleichen
 
Das zeigt mir Delphi als Beispiel. Hoffe das hilft dir weiter. ;)

property ScanLine[Row: Integer]: Pointer;

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);

// Dieses Beispiel zeigt das direkte Zeichnen in das Bitmap
var
  x,y : Integer;
  BitMap : TBitMap;
  P : PByteArray;
begin
  BitMap := TBitMap.create;
  try
    BitMap.LoadFromFile('C:\Programme\Gemeinsame Dateien\Borland Shared\Images\Splash\256color\factory.bmp');
    for y := 0 to BitMap.Height -1 do
    begin
      P := BitMap.ScanLine[y];
      for x := 0 to BitMap.Width -1 do

        P[x] := y;
    end;
    Canvas.Draw(0,0,BitMap);
  finally
    BitMap.Free;
  end;
end;

KahPee 1. Feb 2010 13:41

Re: zwei Bitmaps vergleichen
 
ehm ja... Ich bin glaube ich zusehr Delphi Laie als das da zu sehen :(...

wie ich die jeweils richtige Zeile auslese hab ich glaube ich schon kappiert:
Delphi-Quellcode:
  if Bild1.scanline[posy+y]=Bild2.Pixels[y] then matchingpix:=matchingpix+1;
Allerdings wird in diesem Fall von Bild 1 die ganze Zeile gescannt. das will ich ja gar nicht :o . Ich möchte, dass ja nur ein bestimmter Teil des 1. Bildes gescannt wird. Wie krieg ich denn da jetzt eine Kontrolle über die gescannten und am Ende auch verglichenen Längen und Positionen der Zeilen?

mfg KahPee

thepaine91 1. Feb 2010 13:50

Re: zwei Bitmaps vergleichen
 
:wall: Das ganze nochmal kommentiert.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);

// Dieses Beispiel zeigt das direkte Zeichnen in das Bitmap
var
  x,y : Integer;
  BitMap : TBitMap;
  P : PByteArray;
begin
  BitMap := TBitMap.create;
  try
    BitMap.LoadFromFile('C:\Programme\Gemeinsame Dateien\Borland Shared\Images\Splash\256color\factory.bmp');
    for y := 0 to BitMap.Height -1 do
    begin
      P := BitMap.ScanLine[y]; // Füllt einen Array of Byte mit den Daten der angegebenen Zeile.
      for x := 0 to BitMap.Width -1 do
        // P = length Bitmap.width -1
// Wenn man jetzt row 1 ausliest und P unser Bytearray ist und dem zu folge P[1] ausliest hätte man das selbe wie Pixels[1,1]
        P[x] := y;
    end;
    Canvas.Draw(0,0,BitMap);
  finally
    BitMap.Free;
  end;
end;
Jetzt soweit verständlich :coder2:

KahPee 1. Feb 2010 13:54

Re: zwei Bitmaps vergleichen
 
Oh.. Das war einfach VIELEN DANK!!

Noch eine ganz kurze Frage. Bei der aktuellen Prozedur wird in dem größeren Bild (Bild1) die ganze Zeil gescannt und anschließend wird nur an einer bestimmten Stelle verglichen. Kann man von vorneherein angeben, dass nur ein teil der Zeil gescannt werden soll um rechenzeit zu sparen?
Ich gehe mal davon aus, dass der array mit "0" anfängt ;)

mdf Kahpee

Aphton 1. Feb 2010 14:13

Re: zwei Bitmaps vergleichen
 
Zitat:

Zitat von thepaine91
:wall: Das ganze nochmal kommentiert.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);

// Dieses Beispiel zeigt das direkte Zeichnen in das Bitmap
var
  x,y : Integer;
  BitMap : TBitMap;
  P : PByteArray;
begin
  BitMap := TBitMap.create;
  try
    BitMap.LoadFromFile('C:\Programme\Gemeinsame Dateien\Borland Shared\Images\Splash\256color\factory.bmp');
    for y := 0 to BitMap.Height -1 do
    begin
      P := BitMap.ScanLine[y]; // Füllt einen Array of Byte mit den Daten der angegebenen Zeile.
      for x := 0 to BitMap.Width -1 do
        // P = length Bitmap.width -1
// Wenn man jetzt row 1 ausliest und P unser Bytearray ist und dem zu folge P[1] ausliest hätte man das selbe wie Pixels[1,1]
        P[x] := y;
    end;
    Canvas.Draw(0,0,BitMap);
  finally
    BitMap.Free;
  end;
end;
Jetzt soweit verständlich :coder2:

:wall: Das ganze nochmal verbessert

Du weißt schon, dass das so nicht korrekt ist?
Es gibt soetwas, dass nennt sich Pixelformat. Falls es beispielsweise auf pf24Bit gesetzt ist,
besteht das Bild (bzw dann die einzelnen Rows) aus aneinander gereihten 24/8 Bytes -> r, g, b; wobei die Reihenfolge nicht die gleiche sein muss...

Sieh dir das hier mal an:
Delphi-Quellcode:
var
  Pixel  : PByte;
  y, k, x : Integer;
  bytes  : Byte;
const
  PixelFormatBytes: Array[TPixelFormat] of Byte = ( 0, 0, 0, 1, 0, 2, 3, 4, 0 );
begin
  bytes := PixelFormatBytes[bmp.PixelFormat];
  if bytes = 0 then
    Exit; // PixelFormat wird nicht unterstützt ... kannst du dann gerne von mir aus umändern ...
  for y := 0 to bmp.Height - 1 do
  begin
    Pixel := bmp.Scanline[y];
    for x := 0 to bmp.Width - 1 do
      for k := 0 to bytes - 1 do
      begin
        Pixel^ := 0;
        inc( Pixel );
      end;
  end;
end;

KahPee 1. Feb 2010 14:16

Re: zwei Bitmaps vergleichen
 
Delphi-Quellcode:
function Bitmapcompare(pic1, pic2: Tbitmap; Posx,posy: Integer): Boolean;
var line1,line2: Pbytearray;
    x,y: integer;
    compix, matchpix: integer;
begin
  Result:=false;
  matchpix:=0;
  compix:=0;

  for y := 0 to pic2.Height - 1 do
  begin
    line1:=pic1.ScanLine[posy+y];
    line2:=pic2.ScanLine[y];
    for x := 0 to pic2.width - 1 do
      begin
        if line1[posx+x]=line2[x] then matchpix:=matchpix+1;
        compix:=compix+1;
      end;
  end;

  if compix=matchpix then Result:=true;

end;
Der Code macht seine Sache gut ;). Vielen Dank habs grad ausprobiert und der erste Test verlief erfolgreich :P

mfg KahPee

thepaine91 1. Feb 2010 14:20

Re: zwei Bitmaps vergleichen
 
Nein weis ich nicht weil ich mich noch nie mit TBitmap befasst hatte vorher ich hab nur 2 min die Hilfe durchgeguckt ob ich was finde. ;)
Und da habe ich das wohl übersehen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:29 Uhr.
Seite 1 von 3  1 23      

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