Autor Beitrag
DerHorst
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31

windows200
delphi 6 PE
BeitragVerfasst: Mo 04.10.04 17:51 
Grüß euch!

ich möchste eine simple art von pixelerkennung erstellen.
bsp: ich habe zb ein bmp bild und möchte feststellen welche farbe oder wert das pixel x:= 15 y:=10.

habt ihr vielleicht ne idee wie man das machen kann?


viele grüße

horst
toms
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1099
Erhaltene Danke: 2



BeitragVerfasst: Mo 04.10.04 17:55 
Hi,

ausblenden Delphi-Quelltext
1:
property Pixels[X, Y: Integer]: TColor;					


also z.B Canvas.Pixels[15,10]
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Mo 04.10.04 18:15 
Wenn du nur 1 (oder maximal 2 ;-) ) Pixel auslesen möchtest, dann kannst du ruhig über Pixel gehen. Möchtest du aber dass gesammte Bild durchsuchen empfehle ich auf jeden Fall die Eigenschaft Scanline. Mit der bekommst du direkt einen Pointer auf den Speicher der Zeile zurück und das ist die schnellste Art darauf zuzugreifen. Beachte dabei bitte auch, die Eigenschaft PixelFormat. Die gibt an welches Format du zurückbekommst. Ist ja nicht unbedingt unwichtig. ;-)

PS: Solltest du sehr häufig zwischen den Zeilen springen, dann solltest du dir die Resultate von Scanline in einem dynamischen Array anlegen und darauf zugreifen. Scanlines verursacht nämlich auch ein bisschen overhead.

Und noch etwas am Rande. Vermeide es für jedes Pixel die genaue Position zu berechen.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
var
  Row : pDWord;
  idx : Integer;
begin
  row := Bitmap.Scanline[0];

  for Idx := 0 to Bitmap.Width -1 do begin
    if row^ = clRed then
      // mach was mit dem Pixel

    Inc (Row);        // Nächstes Pixel
    // Achtung!! Das funktioniert so nur mit 32 Bit Bilder, da ein DWord ja auch 32Bit hat.
    // Solltest du ein 24 Bit Bild haben, dann müsstest du einen pByte benutzen und den Pointer um 3 erhöhen.
  end;
end;

Ich glaube das sollte als kleine Anschauung genügen. ;-)

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.
DerHorst Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 31

windows200
delphi 6 PE
BeitragVerfasst: Mo 04.10.04 20:35 
grüß euch.

ich habe das mit dem scanline mal ausprobiert und hänge irgendwie.
als bsp bild habe ich mal ein bmp (32bit) erstellt mit 2 mal 2 pixel.
das pixel oben rechts is rot (ff0000).

hier der code:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
procedure TForm1.BitBtn1Click(Sender: TObject);
var
Row : pDWord;
idx : Integer;

begin
   row := bild.Scanline[0];


  for Idx := 0 to bild.Width -1 do begin
    if row^ = clRed then label2.Caption:= inttostr(idx);


    Inc (Row);        // Nächstes Pixel
    // Achtung!! Das funktioniert so nur mit 32 Bit Bilder, da ein DWord ja auch 32Bit hat.
    // Solltest du ein 24 Bit Bild haben, dann müsstest du einen pByte benutzen und den Pointer um 3 erhöhen.
  end;

end;


jetzt dachte ich eigentlich, das in label2 nun idx dargestellt wird. es tut sich jedoch nicht.

wenn ich im debug mode row auslese bekommem ich:

$D10008
$D1000C

was bedeutet das und wie kann ich über hex werte (ff0000) das pixel abfragen?


grüße

horst
Lossy eX
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1048
Erhaltene Danke: 4



BeitragVerfasst: Mo 04.10.04 21:40 
Also Row ist ein Pointer auf die Daten. Um an die Daten zu gelangen musste den Pointer dereferenzieren. (^) Anderfalls würdest du nur die Addresse auf die der Pointer zeigt verändern.

Wie in dem Beispiel beschrieben untersucht er den Inhalt des Pixels auf eine Farbe. Allerdings bist du einem Trugschluss unterlegen. Nicht $FF0000 ist Rot sondern $0000FF ist rot. Die farben werden folgendermaßen abgelegt. $XXXXXXXX Ist leider so. Warum auch immer.

Edit: Das erste Byte ist in 32 Bit wird nicht benutzt. Also das schwarze.

_________________
Nur die Menschheit ist arrogant genug, um zu glauben sie sei die einzige intelligente Lebensform im All. Wo nicht mal das nachhaltig bewiesen wurde.