AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Wie schwarz-weiß Canvas effizient befüllen?

Ein Thema von iphi · begonnen am 29. Dez 2024 · letzter Beitrag vom 29. Dez 2024
Antwort Antwort
iphi

Registriert seit: 13. Feb 2009
266 Beiträge
 
Delphi 7 Personal
 
#1

Wie schwarz-weiß Canvas effizient befüllen?

  Alt 29. Dez 2024, 10:31
Delphi-Version: 7
Hallo,

ich habe schwarzweiß Pixeldaten in einem Array of Byte, immer 8 Pixel pro Byte.
Momentan fülle ich meinen Canvas mit
Canvas.Pixels[i,j]:=PixelColor; was sehr langsam ist. Gibt es eine Möglichkeit, die 8 Pixels in einem Byte auf einmal zu setzen oder gar eine ganze Zeile?

Tom
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
1.632 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

AW: Wie schwarz-weiß Canvas effizient befüllen?

  Alt 29. Dez 2024, 11:00
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:

https://blog.dummzeuch.de/2019/12/12...lls-in-delphi/

Wobei es im Blog Post allerdings um 24 Bit Farbbitmaps geht, nicht um 8 Bit Graustufen.
Thomas Mueller
  Mit Zitat antworten Zitat
iphi

Registriert seit: 13. Feb 2009
266 Beiträge
 
Delphi 7 Personal
 
#3

AW: Wie schwarz-weiß Canvas effizient befüllen?

  Alt 29. Dez 2024, 11:15
Zitat:
Du meinst Graustufen, nicht schwarz-weiß, oder?
Nein, ich meine tatsächlich schwarzweiß, nur zwei Farben, 1 Bit pro Pixel, 1 Byte = 8 Pixels.
Hilft da ScanLine? Die Funktion war mir bislang nicht geläufig.
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
1.632 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

AW: Wie schwarz-weiß Canvas effizient befüllen?

  Alt 29. Dez 2024, 11:51
Zitat:
Du meinst Graustufen, nicht schwarz-weiß, oder?
Nein, ich meine tatsächlich schwarzweiß, nur zwei Farben, 1 Bit pro Pixel, 1 Byte = 8 Pixels.
Hilft da ScanLine? Die Funktion war mir bislang nicht geläufig.
Hm, ja, auch dann müsste es mit Scanline funktionieren. Dann setzt man je Byte gleich 8 Pixel auf einmal. Das habe ich allerdings noch nie ausprobiert.
Thomas Mueller
  Mit Zitat antworten Zitat
iphi

Registriert seit: 13. Feb 2009
266 Beiträge
 
Delphi 7 Personal
 
#5

AW: Wie schwarz-weiß Canvas effizient befüllen?

  Alt 29. Dez 2024, 12:03
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!
  Mit Zitat antworten Zitat
Benutzerbild von Olli73
Olli73

Registriert seit: 25. Apr 2008
Ort: Neunkirchen
758 Beiträge
 
#6

AW: Wie schwarz-weiß Canvas effizient befüllen?

  Alt 29. Dez 2024, 12:21
Nachdem ich Copilot etwas in die Richtung CreateDIBSection und CopyMemory geschubst habe, kam das hier raus:

Delphi-Quellcode:
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;
Das Format des Arrays muss natürlich passen.
  Mit Zitat antworten Zitat
iphi

Registriert seit: 13. Feb 2009
266 Beiträge
 
Delphi 7 Personal
 
#7

AW: Wie schwarz-weiß Canvas effizient befüllen?

  Alt 29. Dez 2024, 16:55
Bei mir geht es jetzt so:
Delphi-Quellcode:
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;
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.
  Mit Zitat antworten Zitat
Benutzerbild von dummzeuch
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
1.632 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#8

AW: Wie schwarz-weiß Canvas effizient befüllen?

  Alt 29. Dez 2024, 17:54
Das ist bei TBitmap normal. Ich meine mich dunkel zu erinnern, dass man das auch ändern kann, aber ich finde es nicht mehr.
Thomas Mueller
  Mit Zitat antworten Zitat
Redeemer

Registriert seit: 19. Jan 2009
Ort: Kirchlinteln (LK Verden)
1.085 Beiträge
 
Delphi 2009 Professional
 
#9

AW: Wie schwarz-weiß Canvas effizient befüllen?

  Alt 29. Dez 2024, 18:17
Negative Höhe. Geht dich aber auch nichts an.
Janni
2005 PE, 2009 PA, XE2 PA
  Mit Zitat antworten Zitat
Antwort Antwort

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07: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 by Thomas Breitkreuz