In einen Canvas zeichnen mit Alpha-Channel (RGBA)

Für Probleme bezüglich Grafik, Audio, GL, ACS, ...
Antworten
Bernd82
Beiträge: 53
Registriert: Di 22. Sep 2009, 15:12

In einen Canvas zeichnen mit Alpha-Channel (RGBA)

Beitrag von Bernd82 »

Wie kann ich für einen Canvas Zeichenfunktionen aufrufen, die einen Alpha-Channel verwenden? Die gezeichneten graphischen Elemente sollen also z.B. halbtransparent über den vorhandenen Canvas-Inhalt gezeichnet werden. Von AggPas habe ich bereits gehört, es erscheint mir allerdings sehr mächtig.

Scheinbar gibt es FPCanvas und FPColor, ich habe deren Verwendung allerdings noch nicht ergründen können. Die Funktionen müssen unter Windows und Linux laufen, so dass ich einen GDI+ Wrapper wahrscheinlich auch nicht verwenden kann, da es wahrscheinlich GDI+ für Linux nicht gibt.

Danke für jede Unterstützung und

schöne Grüße, Bernd82

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: In einen Canvas zeichnen mit Alpha-Channel (RGBA)

Beitrag von Socke »

In der Theorie musst du nur das richtige Format (24bit Farbe und 8bit Alpha) auswählen und dann mit der passende Farbe (TColor ist 32bit) malen. Für genaueres empfehle ich die Dokumentationen.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Bernd82
Beiträge: 53
Registriert: Di 22. Sep 2009, 15:12

Re: In einen Canvas zeichnen mit Alpha-Channel (RGBA)

Beitrag von Bernd82 »

Hi Socke,

danke für Deine Worte. Wo genau würdest Du suchen? Welche Dokumentation meinst Du, wo finde ich die. Ich habe schon viel herum gesucht, und glaube ich weiß noch gar nicht, welche Doku denn am besten geeignet ist. Bei einem normalen TColor ist doch das MSB bei Windows für die Systemfarben verbraucht und bei Linux unbenutzt :?: Irgendwie find' ich nix Passendes zum Thema :|

Gruß Bernd82

Benutzeravatar
theo
Beiträge: 11103
Registriert: Mo 11. Sep 2006, 19:01

Re: In einen Canvas zeichnen mit Alpha-Channel (RGBA)

Beitrag von theo »

Bernd82: Was willst du denn genau machen?

Bernd82
Beiträge: 53
Registriert: Di 22. Sep 2009, 15:12

Re: In einen Canvas zeichnen mit Alpha-Channel (RGBA)

Beitrag von Bernd82 »

Ich möchte gerne in einem Fenster über dessen vorhandenen Inhalt z.B. eine breite farbige Linie ziehen können, die den Hintergrund aber nicht vollständig verdeckt, sondern in einstellbarem Maße transparent bedeckt. Oder ein Dreieck oder ein Pie oder ein Polygon...

Im angehängten Beispiel werden 3 Kreise übereinander gemalt. Zuerst der rote, dann der grüne, dann der blaue. Der Alpha-Kanal kann im Beispiel von 0..255 also im Umfang eines Bytes wachsen.

Schöne Grüße, Bernd82
Dateianhänge
AlphaBlend.jpg

Benutzeravatar
theo
Beiträge: 11103
Registriert: Mo 11. Sep 2006, 19:01

Re: In einen Canvas zeichnen mit Alpha-Channel (RGBA)

Beitrag von theo »

Mit OpBitmap lässt sich das schon machen. http://www.theo.ch/lazarus/opbitmap64.zip" onclick="window.open(this.href);return false;
Allerdings ist das nicht direkt vorbreitet und benötigt deshalb noch etwas Code.

Code: Alles auswählen

uses opbitmap,lazbridge,opimglib;
 
procedure TForm1.FormPaint(Sender: TObject);
var OutB, TempRed, TempGreen, TempBlue:TCanvasOPBitmap;
GenAlpha:Byte;
 
procedure _SetAlphaForColorAtPos(Bitmap: TCanvasOPBitmap; Pos: TPoint; Alpha: Byte; Tolerance: byte);
var X, Y: integer;
  Value, FindC: Pixel32;
begin
  Bitmap.PixelFormat := pf32bit;
 
  FindC := TBitmapData32(Bitmap.Data).NativePixels[Pos.x, Pos.y];
  for Y := 0 to Bitmap.Height - 1 do
    for X := 0 to Bitmap.Width - 1 do
      if (TBitmapData32(Bitmap.Data).NativePixels[x, y].Red = FindC.Red) and
        (TBitmapData32(Bitmap.Data).NativePixels[x, y].Green = FindC.Green) and
        (TBitmapData32(Bitmap.Data).NativePixels[x, y].Blue = FindC.Blue) then
      begin
        Value := TBitmapData32(Bitmap.Data).NativePixels[x, y];
        Value.Alpha:=Alpha;
        TBitmapData32(Bitmap.Data).NativePixels[x, y] := Value;
      end;
end;
 
procedure _MakeAlphaCircle(var TempB:TCanvasOpBitmap; Color:TColor; Alpha:Byte);
begin
  TempB:=TCanvasOPBitmap.Create;
  TempB.PixelFormat:=pf32bit;
  TempB.Width:=100;
  TempB.Height:=100;
  TempB.Canvas.Brush.Color:=clwhite;
  TempB.Canvas.FillRect(Rect(0,0,TempB.Width,TempB.Height));
  TempB.Canvas.Brush.Color:=Color;
  TempB.Canvas.Pen.Color:=Color;
  TempB.Canvas.Circle(50,50,45);
  TempB.SetAlpha(AlphaTransparent);
  FTFloodFill(TempB,Point(50,50),Color,5);
  _SetAlphaForColorAtPos(TempB,Point(50,50),Alpha,5);
end;
 
begin
  OutB:=TCanvasOPBitmap.Create;
  OutB.PixelFormat:=pf32bit;
  OutB.Width:=Width;
  OutB.Height:=Height;
  OutB.Canvas.Brush.Color:=clwhite;
  OutB.Canvas.FillRect(Rect(0,0,OutB.Width,OutB.Height));
 
  GenAlpha:=191;
  _MakeAlphaCircle(TempRed,clRed,GenAlpha);
  _MakeAlphaCircle(TempGreen,clGreen,GenAlpha);
  _MakeAlphaCircle(TempBlue,clBlue,GenAlpha);
 
  OutB.AlphaBlend:=true;
  OutB.Canvas.Draw(50,50,TempRed);
  OutB.Canvas.Draw(100,50,TempGreen);
  OutB.Canvas.Draw(75,100,TempBlue);
  OutB.Canvas.Resample((Width * 3)  div 4, (Height * 3) div 4); 
  AssignOpBitmapToCanvas(OutB,Canvas,0,0);
  TempRed.free;
  TempGreen.free;
  TempBlue.free;
  OutB.free;
end;
Dateianhänge
alphatest.png
alphatest.png (5.32 KiB) 2785 mal betrachtet

Bernd82
Beiträge: 53
Registriert: Di 22. Sep 2009, 15:12

Re: In einen Canvas zeichnen mit Alpha-Channel (RGBA)

Beitrag von Bernd82 »

Danke für Deine Mühe, Theo! Die Funktion scheint ganz gut zu funktionieren, aber sie ist sehr langsam. Und die erforderlichen einzubindenden Bibliotheken sind leider sehr groß. Ich könnte mir immer auch erst mit einer normalen Zeichenfunktion in ein Bitmap malen und das dann alphamäßig Pixel-für-Pixel mappen.

Kann ich einen TFPCustomCanvas mit TFPColor einsetzen? Wie könnte ich den mit einem normalen TCanvas verknüpfen? Über ein Handle? Über ein Bitmap? Wo gibt es Dokumentation zu TFPCustomCanvas? Ist das einsatzfähig oder noch ein Stub?

Schöne Grüße, Bernd82

Benutzeravatar
theo
Beiträge: 11103
Registriert: Mo 11. Sep 2006, 19:01

Re: In einen Canvas zeichnen mit Alpha-Channel (RGBA)

Beitrag von theo »

Bernd82 hat geschrieben: aber sie ist sehr langsam.
Nö, aber das kann man schon schneller machen, man braucht ja z.B. nicht immer alles neu erstellen, oder den ganzen Bereich zeichnen.
Kommt halt auf die Anwendung an.
Bernd82 hat geschrieben:
Und die erforderlichen einzubindenden Bibliotheken sind leider sehr groß.
Stimmt nicht, du brauchst die ganzen Bildformatleser dafür doch nicht.
Das ist sowieso immer ein seltsames Argument.

Bernd82
Beiträge: 53
Registriert: Di 22. Sep 2009, 15:12

Re: In einen Canvas zeichnen mit Alpha-Channel (RGBA)

Beitrag von Bernd82 »

Hi Theo, Du hast Recht. Ich muss sowieso am Ende Bilder aus mehreren Layern zusammenbauen (also 2,5D). Da könnte ich jeden Layer in einer eigenen Bitmap aufbauen und dann nach Deiner Methode ins Bild mappen. Die Alphamap für jeden Layer bleibt dabei gleich, bzw wird nur selten geändert. Ich werde noch ein wenig herumprobieren.

Zu TFPCustomCanvas und TFPColor gibt es scheinbar keine Doku oder Anwendung? :roll:

Schöne Grüße, Bernd82

Benutzeravatar
theo
Beiträge: 11103
Registriert: Mo 11. Sep 2006, 19:01

Re: In einen Canvas zeichnen mit Alpha-Channel (RGBA)

Beitrag von theo »

Bernd82 hat geschrieben: Ich werde noch ein wenig herumprobieren.
Kannst mich fragen wenn du Probleme hast. Da kann man noch viel optimieren.
Die grösste Bremse ist wahrsch. das Resampling:
OutB.Canvas.Resample((Width * 3) div 4, (Height * 3) div 4);
Das hab ich nur gemacht, damit's hübscher aussieht (leichte Kantenglättung).
Bernd82 hat geschrieben:
Zu TFPCustomCanvas und TFPColor gibt es scheinbar keine Doku oder Anwendung? :roll:
Nicht das ich wüsste. Das war mit ein Grund OpBitmap zu entwickeln. Da ist eigentlich alles wie man's von Delphi kommend erwartet.
fpImage mag genial sein, aber ich habe bisher noch keinen getroffen, der's kapiert ;-)

Antworten