BGRABitmap tutorial 5/de

From Free Pascal wiki
Jump to: navigation, search

Deutsch (de) | English (en) | Français (fr) | Español (es) | Edit

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 mit Ebenen arbeiten 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.

Über Masken

Eine Maske ist ein Graustufenbild. Wenn diese Maske auf ein Bild angewendet wird, werden diejenigen Teile des Bildes, die sich mit den schwarzen Teilen der Maske überschneiden entfernt und werden transparent. Teile des Bildes, die sich mit den weißen Teilen der Maske überschneiden, bleiben hingegen erhalten. Mit anderen Worten: die Maske ist wie ein Alphakanal der die Opazität bestimmt. Ist der Maskenwert null wird das Bild transparent und bei einem Maskenwert von 255 wird es undurchsichtig.

BGRATutorial5d.png

In diesem Beispiel ist das Bild links oben, die Maske rechts oben und das Ergebnis nach Anwendung der Maske links unten.

Der Code in OnPaint :

var temp,tex,mask: TBGRABitmap;
begin
  temp:= TBGRABitmap.Create(640,480,ColorToBGRA(ColorToRGB(clBtnFace)));
 
  //Laden und Skalieren der Textur
  tex := TBGRABitmap.Create('texture.png');
  BGRAReplace(tex,tex.Resample(128,80));
 
  //zeige das Bild in der linken, oberen Ecke
  temp.PutImage(10,10,tex,dmDrawWithTransparency);
 
  //erzeuge eine Maske mit einer Ellipse und einem Rechteck
  mask := TBGRABitmap.Create(128,80,BGRABlack);
  mask.FillEllipseAntialias(40,40,30,30,BGRAWhite);
  mask.FillRectAntialias(60,40,100,70,BGRAWhite);
 
  //zeige die Maske in der rechten, oberen Ecke
  temp.PutImage(150,10,mask,dmDrawWithTransparency);
 
  //wende die Maske auf das Bild an
  tex.ApplyMask(mask);
 
  //zeige das Ergebnisbild in der linken, unteren Ecke
  temp.PutImage(10,100,tex,dmDrawWithTransparency);
 
  mask.Free;
  tex.Free;
 
  //zeige alles auf dem Bildschirm an
  image.Draw(Canvas,0,0,True);
  image.Free;
end;

Entfernen von Teilen des Bildes

Einige Funktionen erlauben es, eine Ellipse zu entfernen, ein Rechteck, etc. Das bedeutet, dass der Teil des Bildes transparent wird. So ist es möglich, ein Loch in ein Bild zu zeichnen. Ist der Alpha-Parameter 255, wird das Loch vollständig transparent. Wenn nicht, dann ist das Loch semi-transparent.

BGRATutorial5e.png

Hier wird links eine Ellipse entfernt mit einem Alpha-Parameter von 255. Rechts wird eine weitere Ellipse entfernt mit einem Alpha-Parameter von 128.

Der Code in OnPaint :

var image,tex: TBGRABitmap;
begin
  image := TBGRABitmap.Create(640,480,ColorToBGRA(ColorToRGB(clBtnFace)));
 
  //Laden und Skalieren der Textur
  tex := TBGRABitmap.Create('texture.png');
  BGRAReplace(tex,tex.Resample(128,80));
 
  //zeige das Bild
  image.PutImage(10,10,tex,dmDrawWithTransparency);
 
  //entferne die Teile
  tex.EraseEllipseAntialias(40,40,30,30,255);
  tex.EraseEllipseAntialias(80,40,30,30,128);
 
  //zeige das Ergebnis
  image.PutImage(10,100,tex,dmDrawWithTransparency);
 
  tex.Free;
 
  //zeige alles auf dem Bildschirm an
  image.Draw(Canvas,0,0,True);
  image.Free;
end;

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 image: TBGRABitmap;
    size: single;
 
  procedure DrawMoon;
  var layer: TBGRABitmap;
  begin
    layer := TBGRABitmap.Create(image.Width,image.Height);
    layer.FillEllipseAntialias(layer.Width/2,layer.Height/2,size*0.4,size*0.4,BGRA(224,224,224,128));
    layer.EraseEllipseAntialias(layer.Width/2+size*0.15,layer.Height/2,size*0.3,size*0.3,255);
    image.PutImage(0,0,layer,dmDrawWithTransparency);
    layer.Free;
  end;
 
begin
  image := TBGRABitmap.Create(ClientWidth,ClientHeight);
 
  //Berechne den verfügbaren Platz in beide Richtungen
  if image.Height < image.Width then
    size := image.Height
  else
    size := image.Width;
 
  image.GradientFill(0,0,image.Width,image.Height,
                     BGRA(128,192,255),BGRA(0,0,255),
                     gtLinear,PointF(0,0),PointF(0,image.Height),
                     dmSet);
 
  DrawMoon;
 
  image.Draw(Canvas,0,0,True);
  image.free;
end;

Die Prozedur erzeugt ein Bild und füllt es mit einem blauen Farbverlauf. Dies ist die Hintergrundebene.

Die Prozedur 'DrawMoon' erzeugt eine Ebene und zeichnet einen Mond darauf. Zuerst wird eine weiße Scheibe gezeichnet, dann eine kleinere Scheibe subtrahiert. Zuletzt wird diese Ebene mit dem Hintergrund verschmolzen.

Starten Sie das Programm

Sie sollten einen Mond vor einem blauen Himmel sehen. Wenn Sie die Größe des Formulars ändern, wird auch der Gradient umgehend angepasst.

Tutorial5a.png

Fügen Sie eine weitere Ebene hinzu mit einer Sonne

Im OnPaint-Ereignis fügen Sie folgende Unterprozedur ein:

  procedure DrawSun;
  var layer,mask: TBGRABitmap;
  begin
    layer := TBGRABitmap.Create(image.Width,image.Height);
    layer.GradientFill(0,0,layer.Width,layer.Height,
                       BGRA(255,255,0),BGRA(255,0,0),
                       gtRadial,PointF(layer.Width/2,layer.Height/2-size*0.15),PointF(layer.Width/2+size*0.45,layer.Height/2-size*0.15),
                       dmSet);
    mask := TBGRABitmap.Create(layer.Width,layer.Height,BGRABlack);
    mask.FillEllipseAntialias(layer.Width/2+size*0.15,layer.Height/2,size*0.25,size*0.25,BGRAWhite);
    layer.ApplyMask(mask);
    mask.Free;
    image.PutImage(0,0,layer,dmDrawWithTransparency);
    layer.Free;
  end;

Diese Prozedur erzeugt einen radialen Farbverlauf von rot zu orange und wendet darauf eine kreisförmige Maske an. Dies ergibt die farbige Scheibe. Zuletzt wird diese Ebene mit dem Hintergrund verschmolzen.

Rufen Sie diese Prozedur so auf, dass die Sonne nach dem Mond gezeichnet wird.

Starten Sie das Programm

Sie sollten eine Sonne und einen Mond vor einem blauen Himmel sehen. Wenn Sie die Größe des Formulars ändern, wird auch der Gradient umgehend angepasst.

BGRATutorial5b.png

Fügen Sie eine Beleuchtungsebene hinzu

Ergänzen Sie die folgende Unterprozedur im OnPaint-Ereignis:

  procedure ApplyLight;
  var layer: TBGRABitmap;
  begin
    layer := TBGRABitmap.Create(image.Width,image.Height);
    layer.GradientFill(0,0,layer.Width,layer.Height,
                       BGRA(255,255,255),BGRA(64,64,64),
                       gtRadial,PointF(layer.Width*5/6,layer.Height/2),PointF(layer.Width*1/3,layer.Height/4),
                       dmSet);
    image.BlendImage(0,0,layer,boMultiply);
    layer.Free;
  end;

Diese Prozedur zeichnet eine Ebene mit einem weißen, radialen Farbverlauf. Sie wird mit dem Bild multipliziert.

Resultierender Code

procedure TForm1.FormPaint(Sender: TObject);
var image: TBGRABitmap;
    size: single;
 
  procedure DrawMoon;
  var layer: TBGRABitmap;
  begin
    layer := TBGRABitmap.Create(image.Width,image.Height);
    layer.FillEllipseAntialias(layer.Width/2,layer.Height/2,size*0.4,size*0.4,BGRA(224,224,224,128));
    layer.EraseEllipseAntialias(layer.Width/2+size*0.15,layer.Height/2,size*0.3,size*0.3,255);
    image.PutImage(0,0,layer,dmDrawWithTransparency);
    layer.Free;
  end;
 
  procedure DrawSun;
  var layer,mask: TBGRABitmap;
  begin
    layer := TBGRABitmap.Create(image.Width,image.Height);
    layer.GradientFill(0,0,layer.Width,layer.Height,
                       BGRA(255,255,0),BGRA(255,0,0),
                       gtRadial,PointF(layer.Width/2,layer.Height/2-size*0.15),PointF(layer.Width/2+size*0.45,layer.Height/2-size*0.15),
                       dmSet);
    mask := TBGRABitmap.Create(layer.Width,layer.Height,BGRABlack);
    mask.FillEllipseAntialias(layer.Width/2+size*0.15,layer.Height/2,size*0.25,size*0.25,BGRAWhite);
    layer.ApplyMask(mask);
    mask.Free;
    image.PutImage(0,0,layer,dmDrawWithTransparency);
    layer.Free;
  end;
 
  procedure ApplyLight;
  var layer: TBGRABitmap;
  begin
    layer := TBGRABitmap.Create(image.Width,image.Height);
    layer.GradientFill(0,0,layer.Width,layer.Height,
                       BGRA(255,255,255),BGRA(64,64,64),
                       gtRadial,PointF(layer.Width*5/6,layer.Height/2),PointF(layer.Width*1/3,layer.Height/4),
                       dmSet);
    image.BlendImage(0,0,layer,boMultiply);
    layer.Free;
  end;
 
begin
  image := TBGRABitmap.Create(ClientWidth,ClientHeight);
 
  if image.Height < image.Width then
    size := image.Height
  else
    size := image.Width;
 
  image.GradientFill(0,0,image.Width,image.Height,
                     BGRA(128,192,255),BGRA(0,0,255),
                     gtLinear,PointF(0,0),PointF(0,image.Height),
                     dmSet);
 
  DrawMoon;
  DrawSun;
  ApplyLight;
 
  image.Draw(Canvas,0,0,True);
  image.free;
end;

Starten Sie das Programm

Sie sollten eine Sonne und einen Mond vor einem blauen Himmel und mit einem Lichteffekt sehen. Wenn Sie die Größe des Formulars ändern, wird auch der Gradient umgehend angepasst.

Tutorial5c.png

Voriges Tutorial (Direkter Zugriff auf die Pixel) | Nächstes Tutorial (Linienarten)