![]() |
pixelweises Zeichnen von PaintBox beschleunigen
Hallo alle zusammen,
ich bin neu hier im Forum und habe auch gleich mal eine erste Frage. Und zwar geht es um folgendes Problem: Ich habe eine alte Gameboy-Cam an einen Mikrocontroller angeschlossen und kann damit pixelweise ein Bild auslesen. Als Ergebnis erhalte ich 128*128=16384 Pixelwerte, jeweils im Bereich von 0 bis 255. Diese Werte sende ich dann via RS232 (serielle Schnittstelle) an den Computer und lese es mit Delphi aus. Die Einzelnen Werte der Pixel speichere ich zur Zeit noch provisorisch in einem Memo, damit ich auch immer sehe, was ankommt. Diese einzelnen Pixelwerte aus der Memo lese ich dann Zeile für Zeile aus, wobei bei mir jeweilt eine Zeile den Wert eines Pixels enthällt. Den jeweils ausgelesenen Wert wandle ich dann in einen Grauwert um und zeichne das jeweilige Pixel mit: Paintbox.Canvas.Pixels[x,y]:='Grauwert' Das ganze wiederhole ich für alle 16384 Pixel und zusätzlich habe ich die Größe der PaintBox von 128x128 auf 256x256 vergrößert, sodass ich mit jedem Pixelgrauwert jeweils 4 Pixel der PaintBox beschreibe. Das ganze funktioniert auch so und ich sehe tatsächlich ein Bild (nach langem Probieren). Es ist allerdings so, das die jetzige Routine zum Zeichnen des Bildes sehr viel Zeit in Anspruch nimmt, 1s oder so. So das man regelrecht zuschauen kann, wie das Bild aufgebaut wird. Jetzt meine Frage: Gibt es eine Möglichkeit das Zeichnen zu beschleunigen? Eine Idee, die ich hatte war, das ganze mit mehreren Threads zu machen. Allerdings kann ich von einem Thread aus nicht direkt die Pixel der PaintBox setzen, sodass die hinfällig ist. Ich hoffe, das mir diesbezüglich jemand weiterhelfen kann. Ich bedanke mich bereits im Voraus für jede Hilfe. ----- mikro |
Re: pixelweises Zeichnen von PaintBox beschleunigen
Holst du dir die Werte mit StrToInt wieder aus dem Memo oder hast du ein eigenes Array dafür?
|
Re: pixelweises Zeichnen von PaintBox beschleunigen
Danke für die wirklich schnelle Antwort.
Zitat:
Würde es denn mit einem Array schneller gehen? |
Re: pixelweises Zeichnen von PaintBox beschleunigen
Hallo,
A: du kannst ein virtuelles Canvas Objekt erstellen, dort zeichen und das fertige Canvas deiner Paintbox zuweisen B: Das Schreiben und lesen aus dem Memo dauert recht lange. Es wäre besser du schreibst die Werte beispielsweise in ein zweidimensionales Array (Entspricht dann direkt auch deiner Canvas-Koordinate) |
Re: pixelweises Zeichnen von PaintBox beschleunigen
Sorry, aber ich bin was Delphi angeht noch kein Profi.
Darum die Vielleicht dumm erscheinende Frage: Was ist eigentlich ein zweidimensionales Array? |
Re: pixelweises Zeichnen von PaintBox beschleunigen
Ich hab das gerade mal mit den virtuellen Canvas probiert, aber ich bekomms einfach nicht hin.
Delphi-Quellcode:
Fehlt da vielleicht noch irgendetwas bei der Erstellung des virtuellen Canvas.
var virtcanvas: Tcanvas;
... virtcanvas.Pixels[x,y]:=Grauwert; Mus man da vielleicht die Größe oder so noch festlegen, und wenn ja, wie macht man das? Height und Widht gibts da ja nicht. |
Re: pixelweises Zeichnen von PaintBox beschleunigen
Ich tippe mal stark darauf, dass Du an der falschen Baustelle werkelst.
Zitat:
|
Re: pixelweises Zeichnen von PaintBox beschleunigen
Zitat:
155200 bps? oder mehr - oder kommst garnicht auf die geschwindigkeit. wenn du jetzt 16348 pixel hast mit jeweils einem byte kommst du auf: 130784 bit. dh. es ist nicht verwunderlich wenn du nur ein bild pro sekunde bekommst. das speicher in ein memo hast du ja eh als temp. bezeichnet also sag ich mal nix dazu. lg Arnulf |
Re: pixelweises Zeichnen von PaintBox beschleunigen
Zitat:
Delphi-Quellcode:
Ich emfpele Dir ein Virtuelles Bitmap, damit ist es einfacher zu "Werkeln". Ein Canvas speichert nicht, sondern Zeichnet nur.
var
virtcanvas: TCanvas; x, y: Integer; begin virtcanvas := TCanvas.Create; for y := 0 to 127 do for x := 0 to 127 do virtcanvas.Pixels[x, y] := RGB(Grauwert, Grauwert, Grauwert); // ... end; Also:
Delphi-Quellcode:
unit Unit1;
interface uses Windows, Messages, ... type TForm1 = class(TForm) PaintBox1: TPaintBox; Button1: TButton; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure PaintBox1Paint(Sender: TObject); procedure Button1Click(Sender: TObject); private { Private-Deklarationen } GBBitmap: TBitmap; procedure ReadGBCamPixels; procedure ZeichneGBBitmap; end; var Form1: TForm1; implementation {$R *.dfm} var GBCamPixelGrauW : Array [0..127, 0..127] of Byte; procedure TForm1.FormCreate(Sender: TObject); begin GBBitmap := TBitmap.Create; // Virt. Bitmap erzeugen GBBitmap.Width := 128; // Grösse festlegen GBBitmap.Height := 128; GBBitmap.Pixelformat := pf8bit; // 256 Farben od. Grauwerte end; procedure TForm1.FormDestroy(Sender: TObject); begin GBBitmap.Free; // Virt. Bitmap freigeben end; procedure TForm1.PaintBox1Paint(Sender: TObject); begin // Das Bitmap in der PBox zeichen (lassen beim verschieben des Frensters etc.) PaintBox1.Canvas.Draw(0, 0, GBBitmap); end; procedure TForm1.ReadGBCamPixels; var x,y : Integer; begin // Einlesen der Cam Werte aus der GBCam. // ... // ... // ... // for y := 0 to 128 do // for x := 0 to 128 do // GBCamPixelGrauW[x, y] := ... end; procedure TForm1.ZeichneGBBitmap; var x,y : Integer; begin // Hiier das Bitmap miit den Farbpixeln zeichnen for y := 0 to 128 do for x := 0 to 128 do GBBitmap.Canvas.Pixels[x, y] := RGB(GBCamPixelGrauW[x, y], GBCamPixelGrauW[x, y], GBCamPixelGrauW[x, y]); end; procedure TForm1.Button1Click(Sender: TObject); begin // The Action ReadGBCamPixels; ZeichneGBBitmap; PaintBox1.Repaint; end; end. |
Re: pixelweises Zeichnen von PaintBox beschleunigen
Vielleicht eine dumme Frage, aber wenn deine Werte zwischen 0 und 255 liegen, dann sind sie nur ein Byte groß, hast du damitnicht schon Grauwerte :?: Oder wie ist das aufgebaut 2 Bit pro Farbe, oder wie?
Mit dem Canvas ist gemeint, das du dir erstmal z.B. ein TBitmap erstells (ohne es anzuzeigen) und dessen Canvas Objekt nimmst, da hast du dann auch die Größeneigenschaften des TBitmaps zu Verfügung. Mehrdimensionale Arrays siehe :arrow: ![]() |
Re: pixelweises Zeichnen von PaintBox beschleunigen
Zitat:
entweder du hast grauwerte - wenn es aber farbwerte sind, dann handelt es sich um eine farbpalette. jede nummer ist also eine farbe. lg Arnulf |
Re: pixelweises Zeichnen von PaintBox beschleunigen
Nochmals riesen DANK an euch.
Das mit dem virtuellen Bitmap werde ich morgen mal probieren, da ich heute leider keine Zeit mehr dazu habe. Die Grauwerte erzeuge ich einfach, indem ich die drei Grundfarben alle in selben Verhältnis mische. Also: Grauwert:= Wert + Wert*256 + Wert*256*256 Dann kann ich die Pixel so beschreiben: canvas.Pixels[x,y]:=Grauwert oder wie turboPascal es geschrieben hat mit: canvas.Pixels[x, y] := RGB(wert, wert, wert); (Danke für den Tipp, ich wusste das bis jetzt noch gar nicht, dass es auch so geht.) |
Re: pixelweises Zeichnen von PaintBox beschleunigen
Ich bleibe dabei, die Bremse ist nicht das Zeichnen sondern die RS232-Schnittstelle...
|
Re: pixelweises Zeichnen von PaintBox beschleunigen
Stichwort: Scanline
|
Re: pixelweises Zeichnen von PaintBox beschleunigen
Zitat:
Wenn 8 Bit Nutzdaten auf die Reise gehen sind es 10 Bit auf der Leitung, da ja Startbit und mindestens ein Stopbit hinzukommen. 128*128*10 = 163840 Bits auf der Leitung Bei 115.200 Baud werden 1,42 Sekunden benötigt. Die Myth Busters würden jetzt sagen "bestätigt". |
Re: pixelweises Zeichnen von PaintBox beschleunigen
shmia, schau mal unauffällig auf Beitrag #8 :mrgreen: :duck:
|
Re: pixelweises Zeichnen von PaintBox beschleunigen
So, das Memo habe ich jetzt rausgeschmissen und anstelle dessen ein zweidimensionales Array verwendet.
Es geht nun auch schon etwas schneller, das Zeichnen, ist aber immer noch zu langsam. Als nächstes werde ich es wohl mal mit nem virtuellen Canvas nochmal probieren. Das die Übertragung der Bilddaten via RS232 recht lange dauert ist mir bekannt. Ich werde deshalb eventuell auf die parallele Schnittstelle umsteigen. Da muss ich dann zwar jedes Byte in Tetraden zerlegen und jedes Halbbyte Einzeln senden, aber ich denke, dass sollte immer noch schneller sein als RS232, wo ja im Prinzip jedes Bit einzeln übertragen wird. Ich habe aber leider bisher noch keine klare Angabe gefunden, mit was für Geschwindigkeiten ich bei der parallelen Schnittstelle arbeiten kann. Kennt sich damit vielleicht jemand aus? Zu meiner aktuellen Übertragungsgeschwindigkeit: Momentan arbeite ich ja noch mit RS232 und 38400 Baud. Mehr geht irgendwie nicht. :( Das scheint irgendwie an Delphi zu liegen. Ich verwende zu Auslesen der seriellen Schnittstelle TComPort. Wenn ich mehr als 38400 Baud vewende kommt delphi mit dem Auslesen aus dem Puffer der seriellen Schnittstelle nicht mehr hinterher und es Fehlen am Ende Werte. :( |
Re: pixelweises Zeichnen von PaintBox beschleunigen
Benutzt Du keinen Hardware-Handshake für die RS232? Und wieso musst Du die Bytes für den Parallelport unbedingt in Nibbles zerlegen? Jeder Parallelport der letzten zehn Jahre kann zumindest EPP und damit volle Bidirektionalität. Also einfach die Datenleitungen als Eingänge konfigurieren und auslesen. Handshake via Strobe geht ja trotzdem.
|
Re: pixelweises Zeichnen von PaintBox beschleunigen
Zitat:
Jetzt ist das zeichnen wirklich wahnsinnig schnell geworden. :-D :-D Danke für den Tipp. Zitat:
|
Re: pixelweises Zeichnen von PaintBox beschleunigen
Keinen Handshake beim RS232 zu verwenden scheint echt ne Krankheit unter µC-Entwicklern zu sein. Lieber die zwei Pins sparen und stattdessen noch zwei mehr I/O-Pins haben ;) Mein Kollege aus der Atmel-Ecke hat das auch immer *sigh* :)
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:21 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