Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Bild Pixel für Pixel / Byte für Byte "zeichnen" (https://www.delphipraxis.net/85053-bild-pixel-fuer-pixel-byte-fuer-byte-zeichnen.html)

hirnstroem 25. Jan 2007 11:10


Bild Pixel für Pixel / Byte für Byte "zeichnen"
 
'loha Folks,

ich wollte mich erkundigen, wie man eine Grafik aus einzelnen Pixeln zusammensetzt.

Ich bekomme von einem Gerät, welches an einen CAN-Bus angeschlossen ist ein Bild zugeschickt. Die Bilddaten, welche ich erhalte sehen z.B. so aus:

2103010000050026 // erstes Byte des Headers
0700000023020026 // zweites Byte des Headers
FF00FF00FF00FF00 // Bilddaten
FF00FF00FF00FF00 // "
FF00FF00FF00FF00 // "
FF00FF00FF00FF00 // "
FF7B7B7B7B7B7B7B // " + bit gestuffe

Aus dem Header kann ich die Höhe und Breite des (momentan unkomprimierten) Bildes entnehmen.

Die Restlichen Daten (im Beispiel die FFs und 00s) stellen die Farbe des jeweiligen Pixels (1 Byte = 1 Farbe) dar. Abgeschlossen wird das Ganze durch Füllbits (im Beispiel die 7Bs), welche mich erkennen lassen, dass keine weiteren Bilddaten mehr folgen.

Nun habe ich also einen ganzen Rattenschwanz an Bilddaten (FFs und 00s), welche nun nacheinander das jeweilige Pixel des Bildes füllen sollen. Aber wie dies geht ist mir z.Z. noch ein Rätsel.

Grüsse
hirnstroem

H4ndy 25. Jan 2007 11:13

Re: Bild Pixel für Pixel / Byte für Byte "zeichnen"
 
Ich würde erstmal versuchen, das ganze über einen File- oder Memory-Stream
zu sammeln und auf die Platte zu schreiben. Vielleicht kommt ja eine
valide Windows-Bitmap raus, hab k.A. wie der Header auszusehen hat ^^"

Edit:
Ansonsten dann halt eine TBitmap-Instanz erzeugen und die Höhe und Breite
setzen. Dann die Pixel durchgehen und deren Farbe entsprechend setzen.

sirius 25. Jan 2007 12:10

Re: Bild Pixel für Pixel / Byte für Byte "zeichnen"
 
Zitat:

Zitat von H4ndy
Ich würde erstmal versuchen, das ganze über einen File- oder Memory-Stream
zu sammeln und auf die Platte zu schreiben. Vielleicht kommt ja eine
valide Windows-Bitmap raus, hab k.A. wie der Header auszusehen hat ^^"

Edit:
Ansonsten dann halt eine TBitmap-Instanz erzeugen und die Höhe und Breite
setzen. Dann die Pixel durchgehen und deren Farbe entsprechend setzen.

Ich würde genau das Edit machen. Mal schauen was funktioniert
-TBitmap.canvas.pixels[a,b]:=Tcolor;
-oder nonVCL über createBitmap

SirThornberry 25. Jan 2007 12:22

Re: Bild Pixel für Pixel / Byte für Byte "zeichnen"
 
ahh, warum so kompliziert. Einfach ein TBitmap erstellen, die Farbtiefe setzen, mit Scanline einen Pointer auf die letzte Zeile holen und da die gesamten Daten rein schreiben. Dabei natürlich beachten das die Zeile an 32bit ausgerichtet ist und somit gegebenfalls einige Bits ungenutzt bleiben pro zeile.

hirnstroem 25. Jan 2007 12:36

Re: Bild Pixel für Pixel / Byte für Byte "zeichnen"
 
Das überfordert nun meine Delphi-Skills ein wenig.

Delphi-Quellcode:
  Picture := TBitmap.Create;
  Picture.Width := PictureWidth;
  Picture.Height := PictureHeight;
  Picture.PixelFormat := pf8bit;
Bis hierhin ist mir die Geschichte noch klar.

Wie kann ich jetzt z.B. das erste Pixel eines 5 x 7 Pixel "grossen" Bildes mit der Information 'FF' oder '00' versehen?

SirThornberry 25. Jan 2007 12:40

Re: Bild Pixel für Pixel / Byte für Byte "zeichnen"
 
mit
Delphi-Quellcode:
Bitmap.Scanline[Bitmap.Height - 1]
bekommst du einen Pointer auf die letzte Zeile. Bitmaps sind so aufgebaut das im Speicher erst die letzte Zeile steht, dann die vorletzte, dann die 3letzte etc.
Das heißt du musst zu dieser Adresse 2 Zeilenlängen addieren um an den Anfang der ersten Zeile zu gelangen.

Namenloser 25. Jan 2007 13:03

Re: Bild Pixel für Pixel / Byte für Byte "zeichnen"
 
edit: >.< dummheit, hab den post nich richtig gelesen >.< sry...

hirnstroem 26. Jan 2007 11:33

Re: Bild Pixel für Pixel / Byte für Byte "zeichnen"
 
Vielen Dank so weit. Das Bild sieht schon mehr oder weniger so aus wie es soll. Aber die einzelnen Pixel scheinen jeweils um ein Paar Positionen verschoben zu sein.

Delphi-Quellcode:
  PictureWidth := 5;
  PictureHeight := 7;
  PixelBytes := 'FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF00FF'
^^ so sieht die Situation beispielsweise aus bevor das Bild aufgebaut wird. In PixelBytes sind 35 Pixel gespeichert, welche ein 7x5 Pixel grosses Bild mit einem Schachbrettmuster ergäben. Die Bytes in PixelBytes sind so angeordnet, dass das erste den oberen rechten Pixel des Bildes und das letzte den Pixel unten Links im Bild darstellen. Mit dem nachfolgenden Code wird nun von hinten her jedes Pixel geschrieben:

Delphi-Quellcode:
for k := 0 to PictureHeight - 1 do
begin
  Pixel := Picture.ScanLine[k];
  for l := 0 to PictureWidth - 1 do // row manipulation
  begin
    with Picture do
    begin
      Color := HexStrToInt(Copy(PixelBytes, Length(PixelBytes) - 1, 2));

      if Color = 255 then Color := 125; // nur damit ich weisse Pixel auch sehe

      Pixel^.rgbtRed  := Color;
      Pixel^.rgbtGreen := Color;
      Pixel^.rgbtBlue := Color;

      PixelBytes := Copy(PixelBytes, 0, Length(PixelBytes) - 2);
      Inc(Pixel);
    end;
  end;
end;
Picture.SaveToFile(IntToStr(k) + '.bmp');
Nun erwarte ich eigentlich nach dem speichern des Bildes, dass dieses in etwa so aussieht (x = weiss, - = schwarz):

x-x-x-x
-x-x-x-
x-x-x-x
-x-x-x-
x-x-x-x
-x-x-x-
x-x-x-x

Heraus kommt aber folgendes:

x---x
-xxx-
x---x
-xxx-
x---x
-xxx-
---xx

Und das gefällt mir nicht.

hirnstroem 26. Jan 2007 11:34

Re: Bild Pixel für Pixel / Byte für Byte "zeichnen"
 
*kreuzsternrautetotenkopffluch*

Ich habe die Farbtiefe (PixelFormat) auf 8 bit anstatt 32 bit eingestellt. Mit 32 Bit kommt die Sache richtig raus.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:30 Uhr.

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