Difference between revisions of "BGRABitmap tutorial 4/de"

From Lazarus wiki
Jump to navigationJump to search
m (Fixed syntax highlighting; deleted category already in page template)
 
(3 intermediate revisions by 3 users not shown)
Line 12: Line 12:
  
 
Im Objektinspektor fügen Sie einen OnPaint-Handler hinzu und schreiben Sie:
 
Im Objektinspektor fügen Sie einen OnPaint-Handler hinzu und schreiben Sie:
<delphi>procedure TForm1.FormPaint(Sender: TObject);
+
<syntaxhighlight lang="pascal">procedure TForm1.FormPaint(Sender: TObject);
 
var x,y: integer;
 
var x,y: integer;
 
     p: PBGRAPixel;
 
     p: PBGRAPixel;
Line 35: Line 35:
 
   image.Draw(Canvas,0,0,True);
 
   image.Draw(Canvas,0,0,True);
 
   image.free;
 
   image.free;
end;</delphi>
+
end;</syntaxhighlight>
  
 
Diese Prozedur erzeugt eine Bitmap von der selben Größe wie der verfügbare Clientspace. Dann greifen die Schleifen direkt auf die Pixeldaten zu und erstellen einen bidirektionalen Farbverlauf. Zuletzt wird das Bild gezeichnet und der Speicher freigegeben.
 
Diese Prozedur erzeugt eine Bitmap von der selben Größe wie der verfügbare Clientspace. Dann greifen die Schleifen direkt auf die Pixeldaten zu und erstellen einen bidirektionalen Farbverlauf. Zuletzt wird das Bild gezeichnet und der Speicher freigegeben.
  
 
Beim Zugriff auf die Bitmapdaten verwenden Sie entweder Data (wenn es nicht auf die Reihenfolge der Zeilen ankommt) oder Scanline (greift auf eine bestimmte Zeile zu). Innerhalb einer Zeile sind die Pixel von links nach rechts angeordnet. Dadurch ist jede Komponente definiert. Zum Beispiel:
 
Beim Zugriff auf die Bitmapdaten verwenden Sie entweder Data (wenn es nicht auf die Reihenfolge der Zeilen ankommt) oder Scanline (greift auf eine bestimmte Zeile zu). Innerhalb einer Zeile sind die Pixel von links nach rechts angeordnet. Dadurch ist jede Komponente definiert. Zum Beispiel:
<delphi>p^.red := x*256 div image.Width;</delphi>
+
<syntaxhighlight lang="pascal">p^.red := x*256 div image.Width;</syntaxhighlight>
 
Definiert einen Rotanteil, der von 0 (links) bis 255 (rechts) reicht. Der Maximalwert von 'image.Width' wird nie durch x erreicht und somit erreicht auch der Rotanteil nie 256.
 
Definiert einen Rotanteil, der von 0 (links) bis 255 (rechts) reicht. Der Maximalwert von 'image.Width' wird nie durch x erreicht und somit erreicht auch der Rotanteil nie 256.
  
Line 53: Line 53:
 
Sie können auch die HSLA-Farbskala ansprechen (Hue=Farbton, Saturation=Sättigung, Lightness=Helligkeit). Dazu deklarieren Sie ein THSLAPixel. Seine Werte reichen von 0 bis 65535. Um es in ein Standard-RGB-Pixel zu konvertieren, verwenden Sie die Routine 'HSLAToBGRA'.
 
Sie können auch die HSLA-Farbskala ansprechen (Hue=Farbton, Saturation=Sättigung, Lightness=Helligkeit). Dazu deklarieren Sie ein THSLAPixel. Seine Werte reichen von 0 bis 65535. Um es in ein Standard-RGB-Pixel zu konvertieren, verwenden Sie die Routine 'HSLAToBGRA'.
  
<delphi>procedure TForm1.FormPaint(Sender: TObject);
+
<syntaxhighlight lang="pascal">procedure TForm1.FormPaint(Sender: TObject);
 
var x,y: integer;
 
var x,y: integer;
 
     p: PBGRAPixel;
 
     p: PBGRAPixel;
Line 77: Line 77:
 
   image.Draw(Canvas,0,0,True);
 
   image.Draw(Canvas,0,0,True);
 
   image.free;
 
   image.free;
end;  </delphi>
+
end;  </syntaxhighlight>
  
 
[[Image:BGRATutorial4b.png]]
 
[[Image:BGRATutorial4b.png]]
 +
 +
==== Farbkorrektur ====
 +
 +
Die HSLA-Farben haben eine Gamma-Korrektur, aber es gibt auch andere mögliche Korrekturen. Beispielsweise steht H für "Hue" (= Farbton). In der klassischen Version des HSLA-Modells ist jeder Bereich zwischen den Primärfarben (rot/grün/blau) in 120 Grad unterteilt, wodurch sich 21845 Farben in THSLAPixel ergeben. Allerdings können wir die Farbunterschiede in diesen verschiedenen Bereichen nicht gleichermaßen empfinden. Die Funktionen HtoG und GtoH aaktivieren bzw. deaktivieren eine Korrektur, wodurch im G-Farbbereich die Teilbereiche nicht mehr dieselbe Größe haben. Um einen korrigierten Farbton zu erhalten, schreiben Sie:
 +
<syntaxhighlight lang="pascal">
 +
hsla.hue := GtoH(x*65536 div image.Width);
 +
</syntaxhighlight>
 +
 +
Beachten Sie, dass der Bereich der Orangetöne breiter wird. Zuletzt entspricht im HSLA-Modell die Helligkeit L (lightness) nicht der empfundenen Helligkeit. Anstatt nur den Farbton zu korrigieren, können Sie GSBAToBGRA und BGRAToGSBA anstelle von HLSAToBGRA und BGRAToHSLA verwenden. Das G bedeutet hier, dass der Farbton automatisch korrigiert wird und das B (Brightness) steht für die empfundene Helligkeit (manchmal auch Beleuchtung genannt), die hier ebenfalls Berücksichtigung findet. So müssen Sie nicht ausdrücklich GtoH und HtoG aufrufen.
 +
 +
Der Code wird einfach zu:
 +
<syntaxhighlight lang="pascal">procedure TForm1.FormPaint(Sender: TObject);
 +
var x,y: integer;
 +
    p: PBGRAPixel;
 +
    image: TBGRABitmap;
 +
    hsla: THSLAPixel;
 +
begin
 +
  image := TBGRABitmap.Create(ClientWidth,ClientHeight);
 +
  hsla.lightness := 32768;
 +
  hsla.alpha := 65535;
 +
  for y := 0 to image.Height-1 do
 +
  begin
 +
    p := image.Scanline[y];
 +
    hsla.saturation := y*65536 div image.Height;
 +
    for x := 0 to image.Width-1 do
 +
    begin
 +
      hsla.hue := x*65536 div image.Width;
 +
      p^:= GSBAToBGRA(hsla);
 +
      inc(p);
 +
    end;
 +
  end;
 +
  image.InvalidateBitmap; // changed by direct access
 +
 +
  image.Draw(Canvas,0,0,True);
 +
  image.free;
 +
end;  </syntaxhighlight>
 +
 +
Achten Sie darauf, den Typ THSLAPixel einzusetzen, unabhängig von der Korrektur des Farbmodells.
 +
 +
=== Starten Sie das Programm ===
 +
 +
Mit voller Farbkorrektur ist der Farbverlauf progressiver, und ähnelt dem, den Sie mit dem Lab-Farbmodell erhalten würden.
 +
 +
[[Image:BGRATutorial4c.png]]
 +
  
 
[[BGRABitmap tutorial 3/de|Voriges Tutorial (Zeichnen mit der Maus)]] | [[BGRABitmap tutorial 5/de|Nächstes Tutorial (Ebenen und Masken)]]
 
[[BGRABitmap tutorial 3/de|Voriges Tutorial (Zeichnen mit der Maus)]] | [[BGRABitmap tutorial 5/de|Nächstes Tutorial (Ebenen und Masken)]]
 
[[Category:Graphics/de]]
 

Latest revision as of 06:03, 10 February 2020

Deutsch (de) English (en) español (es) français (fr)


Home | Tutorial 1 | Tutorial 2 | Tutorial 3 | Tutorial 4 | Tutorial 5 | Tutorial 6 | Tutorial 7 | Tutorial 8 | Tutorial 9 | Tutorial 10 | Tutorial 11 | Tutorial 12 | Tutorial 13 | Tutorial 14 | Tutorial 15 | Tutorial 16 | Edit

Dieses Tutorial zeigt, wie Sie direkt auf die Pixel zugreifen können.

Erzeugen Sie ein neues Projekt

Erzeugen Sie ein neues Projekt und fügen Sie eine Referenz auf BGRABitmap hinzu, genau so wie im ersten Tutorial.

Fügen Sie einen Zeichen-Handler hinzu

Im Objektinspektor fügen Sie einen OnPaint-Handler hinzu und schreiben Sie:

procedure TForm1.FormPaint(Sender: TObject);
var x,y: integer;
    p: PBGRAPixel;
    image: TBGRABitmap;
begin
  image := TBGRABitmap.Create(ClientWidth,ClientHeight);

  for y := 0 to image.Height-1 do
  begin
    p := image.Scanline[y];
    for x := 0 to image.Width-1 do
    begin
      p^.red := x*256 div image.Width;
      p^.green := y*256 div image.Height;
      p^.blue := 0;
      p^.alpha := 255;
      inc(p);
    end;
  end;
  image.InvalidateBitmap; // geändert durch direkten Zugriff

  image.Draw(Canvas,0,0,True);
  image.free;
end;

Diese Prozedur erzeugt eine Bitmap von der selben Größe wie der verfügbare Clientspace. Dann greifen die Schleifen direkt auf die Pixeldaten zu und erstellen einen bidirektionalen Farbverlauf. Zuletzt wird das Bild gezeichnet und der Speicher freigegeben.

Beim Zugriff auf die Bitmapdaten verwenden Sie entweder Data (wenn es nicht auf die Reihenfolge der Zeilen ankommt) oder Scanline (greift auf eine bestimmte Zeile zu). Innerhalb einer Zeile sind die Pixel von links nach rechts angeordnet. Dadurch ist jede Komponente definiert. Zum Beispiel:

p^.red := x*256 div image.Width;

Definiert einen Rotanteil, der von 0 (links) bis 255 (rechts) reicht. Der Maximalwert von 'image.Width' wird nie durch x erreicht und somit erreicht auch der Rotanteil nie 256.

Starten Sie das Programm

Sie sollten ein Formular mit einem Farbverlauf sehen. Die Ecken sind schwarz, rot, gelb und grün. Wenn Sie die Größe des Formulars ändern, wird auch der Gradient umgehend angepasst.

BGRATutorial4.png

Verwendung des HSLA Farbraumes

Sie können auch die HSLA-Farbskala ansprechen (Hue=Farbton, Saturation=Sättigung, Lightness=Helligkeit). Dazu deklarieren Sie ein THSLAPixel. Seine Werte reichen von 0 bis 65535. Um es in ein Standard-RGB-Pixel zu konvertieren, verwenden Sie die Routine 'HSLAToBGRA'.

procedure TForm1.FormPaint(Sender: TObject);
var x,y: integer;
    p: PBGRAPixel;
    image: TBGRABitmap;
    hsla: THSLAPixel;
begin
  image := TBGRABitmap.Create(ClientWidth,ClientHeight);
  hsla.lightness := 32768;
  hsla.alpha := 65535;
  for y := 0 to image.Height-1 do
  begin
    p := image.Scanline[y];
    hsla.saturation := y*65536 div image.Height;
    for x := 0 to image.Width-1 do
    begin
      hsla.hue := x*65536 div image.Width;
      p^:= HSLAToBGRA(hsla);
      inc(p);
    end;
  end;
  image.InvalidateBitmap; // geändert durch direkten Zugriff

  image.Draw(Canvas,0,0,True);
  image.free;
end;

BGRATutorial4b.png

Farbkorrektur

Die HSLA-Farben haben eine Gamma-Korrektur, aber es gibt auch andere mögliche Korrekturen. Beispielsweise steht H für "Hue" (= Farbton). In der klassischen Version des HSLA-Modells ist jeder Bereich zwischen den Primärfarben (rot/grün/blau) in 120 Grad unterteilt, wodurch sich 21845 Farben in THSLAPixel ergeben. Allerdings können wir die Farbunterschiede in diesen verschiedenen Bereichen nicht gleichermaßen empfinden. Die Funktionen HtoG und GtoH aaktivieren bzw. deaktivieren eine Korrektur, wodurch im G-Farbbereich die Teilbereiche nicht mehr dieselbe Größe haben. Um einen korrigierten Farbton zu erhalten, schreiben Sie:

hsla.hue := GtoH(x*65536 div image.Width);

Beachten Sie, dass der Bereich der Orangetöne breiter wird. Zuletzt entspricht im HSLA-Modell die Helligkeit L (lightness) nicht der empfundenen Helligkeit. Anstatt nur den Farbton zu korrigieren, können Sie GSBAToBGRA und BGRAToGSBA anstelle von HLSAToBGRA und BGRAToHSLA verwenden. Das G bedeutet hier, dass der Farbton automatisch korrigiert wird und das B (Brightness) steht für die empfundene Helligkeit (manchmal auch Beleuchtung genannt), die hier ebenfalls Berücksichtigung findet. So müssen Sie nicht ausdrücklich GtoH und HtoG aufrufen.

Der Code wird einfach zu:

procedure TForm1.FormPaint(Sender: TObject);
var x,y: integer;
    p: PBGRAPixel;
    image: TBGRABitmap;
    hsla: THSLAPixel;
begin
  image := TBGRABitmap.Create(ClientWidth,ClientHeight);
  hsla.lightness := 32768;
  hsla.alpha := 65535;
  for y := 0 to image.Height-1 do
  begin
    p := image.Scanline[y];
    hsla.saturation := y*65536 div image.Height;
    for x := 0 to image.Width-1 do
    begin
      hsla.hue := x*65536 div image.Width;
      p^:= GSBAToBGRA(hsla);
      inc(p);
    end;
  end;
  image.InvalidateBitmap; // changed by direct access

  image.Draw(Canvas,0,0,True);
  image.free;
end;

Achten Sie darauf, den Typ THSLAPixel einzusetzen, unabhängig von der Korrektur des Farbmodells.

Starten Sie das Programm

Mit voller Farbkorrektur ist der Farbverlauf progressiver, und ähnelt dem, den Sie mit dem Lab-Farbmodell erhalten würden.

BGRATutorial4c.png


Voriges Tutorial (Zeichnen mit der Maus) | Nächstes Tutorial (Ebenen und Masken)