Autor Beitrag
P@u1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 117



BeitragVerfasst: Mi 25.08.10 15:17 
Hi,

ich arbeite zurzeit an einer von TBitMap abgeleiteten Klasse, die ein paar Erweiterungen enthalten soll.
Derzeit arbeite ich daran, möglichst schnell den Bildschirm nach dem Bild zu durchsuchen, also es wird nach einer exakten Übereinstimmung gesucht.
Dazu benutze ich folgende Funktionen:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
function TBitMapEx.FindInScreen: TPoint;
var
  tempbmp: TBitMapEx;
  tempbmp2: TBitMapEx;
  i: Integer;
  j: Integer;
begin
  result:=Point(-1,-1);
  tempbmp:=TBitMapEx.Create;
  tempbmp.GetScreenShot;
  tempbmp2:=TBitMapEx.Create;
  tempbmp2.Width:=100;
  tempbmp2.Height:=100;
  for i := 0 to Screen.Height - 1 - self.Height do
  begin
    for j := 0 to Screen.Width - 1 - self.Width do
    begin
      tempbmp2.Canvas.CopyRect(Rect(j,i,j+self.Width,i+self.Height),tempbmp.Canvas,Rect(0,0,self.Width-1,self.Height-1));
{hier bin ich mir nicht sicher, ob und an welchen Stellen -1 rein muss oder nicht, habe aber auch damit schon einiges versucht.}
 
      if self.IsEqual(tempbmp2) then
      begin
        result:=Point(j,i);
        tempbmp.Free;
        tempbmp2.Free;
        exit;
      end;
    end;
  end;

  tempbmp.Free;
  tempbmp2.Free;
end;


Hier dann noch der Code der verwendeten Funktion IsEqual, die habe ich selbst geschrieben, weil ich auf anhieb keine ähnliche Funktion von BitMap gefunden habe.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
function TBitMapEx.IsEqual(bmp: TBitMap): Boolean;
type
  TPixArray = Array[1..3of Byte;
var
  a,b: ^TPixArray;
  i,j: integer;
begin
  result:=false;
  self.PixelFormat:=pf24bit;
  bmp.PixelFormat:=pf24bit;

  if (bmp.Height <> self.Height) or (bmp.Width <> self.Width) then
  begin
    Raise Exception.Create('Size does not match!');
    exit;
  end;

  for i := 0 to bmp.Height - 1 do
  begin
    a:=self.ScanLine[i];
    b:=bmp.ScanLine[i];
    for j := 0 to bmp.Width - 1 do
    begin
      if a^[1] <> b^[1then
        exit;
      if a^[2] <> b^[2then
        exit;
      if a^[3] <> b^[3then
        exit;

      inc(a);
      inc(b);
    end;
  end;
  result:=true;
end;


Mit IsEqual habe ich einen kurzen Test gemacht und es scheint zu funktionieren.
Die Hauptfunktion (FindInScreen) funktioniert leider überhaupt nicht, es kommt immer der Punkt -1,-1 raus.
Ich wäre euch sehr dankbar, falls ihr mir helfen könntet, den Fehler zu finden, ich habe schon ziemlich lange danach gesucht und einige Tests gemacht, auch z.B. indem ich Paint geöffnet habe und (fast) den ganzen Bildschirm weiß gemacht habe und dann zum Test ein weißes Bild mit 100x100 genommen, es wurde trotzdem nicht gefunden, ich kommme leider einfach nicht drauf, wo der Fehler ist.
Natürlich kann ich verstehen, wenn ihr keine Lust habt, die Fehler anderer Leute zu suchen, aber falls euch auf anhieb etwas auffallen sollte, wäre ich für Hilfe sehr dankbar.
Auch wenn ihr allgemeines entdeckt wie schlechter Stil oder mir bessere Möglichkeiten aufzeigen könnt, wäre das sehr toll.
Bei Bedarf kann ich auch die ganze Unit hochladen, aber im Moment kommt es mir nur auf diese beiden Funktionen an.
P.S.: Im Quelltext steht noch eine Art Frage in Form eines Kommentars.

Edit: Hab den Fehler inzwischen doch noch gefunden.
Beim CopyRect hab ich Dest mit Source vertauscht, also die Reihenfolge der Koordinaten.