![]() |
Delphi-Version: 7
Wie schwarz-weiß Canvas effizient befüllen?
Hallo,
ich habe schwarzweiß Pixeldaten in einem Array of Byte, immer 8 Pixel pro Byte. Momentan fülle ich meinen Canvas mit
Delphi-Quellcode:
was sehr langsam ist. Gibt es eine Möglichkeit, die 8 Pixels in einem Byte auf einmal zu setzen oder gar eine ganze Zeile?
Canvas.Pixels[i,j]:=PixelColor;
Tom |
AW: Wie schwarz-weiß Canvas effizient befüllen?
Du meinst Graustufen, nicht schwarz-weiß, oder?
Schneller als Pixel[] ist der Zugriff über Scanline, und das um Größenordnungen. Und selbst das kann man noch verbessern, indem man die Zahl der Scanline-Aufrufe reduziert, denn auch die sind relativ aufwändig. Ich habe darüber mal vor Urzeiten geblogt: ![]() Wobei es im Blog Post allerdings um 24 Bit Farbbitmaps geht, nicht um 8 Bit Graustufen. |
AW: Wie schwarz-weiß Canvas effizient befüllen?
Zitat:
Hilft da ScanLine? Die Funktion war mir bislang nicht geläufig. |
AW: Wie schwarz-weiß Canvas effizient befüllen?
Zitat:
|
AW: Wie schwarz-weiß Canvas effizient befüllen?
Hab gerade Dein Tutorial gelesen, ist prima! :-)
Ich glaube, jetzt hab ich verstanden wie das mit ScanLine geht. Per ScanLine bekomme ich die Startadresse der Pixeldaten. Dann muss ich nur noch meine Daten rein kopieren. Probiere ich gleich mal aus. Danke für den Tipp! |
AW: Wie schwarz-weiß Canvas effizient befüllen?
Nachdem ich Copilot etwas in die Richtung CreateDIBSection und CopyMemory geschubst habe, kam das hier raus:
Delphi-Quellcode:
Das Format des Arrays muss natürlich passen.
uses
Windows, Graphics, SysUtils; type TByteArray = array of Byte; procedure CreateMonochromeBitmapWithCopyMemory(const ByteArray: TByteArray; Width, Height: Integer); var Bitmap: HBITMAP; DC: HDC; Bits: Pointer; BitmapInfo: TBitmapInfo; RowBytes: Integer; begin // Bitmap-Info initialisieren ZeroMemory(@BitmapInfo, SizeOf(BitmapInfo)); with BitmapInfo.bmiHeader do begin biSize := SizeOf(TBitmapInfoHeader); biWidth := Width; biHeight := -Height; // Top-Down biPlanes := 1; biBitCount := 1; // 1-Bit Farbtiefe (monochrom) biCompression := BI_RGB; end; // Device Context erstellen DC := GetDC(0); try // DIB-Section erstellen Bitmap := CreateDIBSection(DC, BitmapInfo, DIB_RGB_COLORS, Bits, 0, 0); if Bitmap = 0 then raise Exception.Create('CreateDIBSection fehlgeschlagen'); // Breite der Bitmap-Zeile in Bytes (jedes Bit repräsentiert einen Pixel) RowBytes := ((Width + 31) div 32) * 4; // Pixelarray kopieren CopyMemory(Bits, @ByteArray[0], Min(Length(ByteArray), RowBytes * Height)); // Das Bitmap weiterverarbeiten (z.B. in eine TBitmap laden) with TBitmap.Create do try Handle := Bitmap; SaveToFile('MonochromeBitmapWithCopyMemory.bmp'); // Speichern des Bitmaps als Datei finally Free; end; finally ReleaseDC(0, DC); end; end; |
AW: Wie schwarz-weiß Canvas effizient befüllen?
Bei mir geht es jetzt so:
Delphi-Quellcode:
Eine Sache wundert mich: Die Zeilen sind im Speicher umgekehrt angeordnet, d.h. die unterste Zeile mit der höchsten Zeilennummer steht an der niedrigsten Speicheradresse.
procedure TForm1.DrawLinesFast(l: TLines);
var bm: TBitmap; i: Integer; w,h: integer; p: pointer; begin h:=length(l); if h=0 then exit; w:=length(l[0].b); if w=0 then exit; bm := TBitmap.Create; Try bm.PixelFormat := pf1bit; bm.Width:=w*8; bm.Height:=h; bm.Canvas.Refresh; for i:=0 to h-1 do begin p:=bm.ScanLine[i]; move(l[i].b[0],p^,w); end; Im.Picture.Assign(bm); Finally bm.Free; End; end; |
AW: Wie schwarz-weiß Canvas effizient befüllen?
Das ist bei TBitmap normal. Ich meine mich dunkel zu erinnern, dass man das auch ändern kann, aber ich finde es nicht mehr.
|
AW: Wie schwarz-weiß Canvas effizient befüllen?
Negative Höhe. Geht dich aber auch nichts an.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:40 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