Splash Screen transparant?

Rund um die LCL und andere Komponenten
MmVisual
Beiträge: 1120
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winux (L 1.6 FPC 3)
CPU-Target: 32/64Bit

Splash Screen transparant?

Beitrag von MmVisual »

Hallo,

Ich habe eine PNG Datei mit transparentem Hintergrund. Diese möchte ich so beim Start der EXE in der Bildschirmmitte anzeigen.

Neues Formular erzeugen, das Bild rein setzen, soweit klappt das.

Aber wie mache ich von dem Fenster den transparenten Teil der Grafik transparent?

Das ist der Code den ich bisher geschrieben habe:

Code: Alles auswählen

procedure TfrmSplash.FormCreate(Sender: TObject);
begin
  frmSplash := Self;
  ShapeControl(Self);
end;
 
procedure TfrmSplash.ShapeControl(AControl: TWinControl);
var
  ABitmap: TBitmap;
  x, y: Integer;
begin
  ABitmap := TBitmap.Create;
  ABitmap.Width := Image1.Picture.Bitmap.Width;
  ABitmap.Height := Image1.Picture.Bitmap.Height;
  ABitmap.Monochrome := True;
  ABitmap.Canvas.Brush.Color := clBlack; // transparent color
  ABitmap.Canvas.FillRect(0, 0, ABitmap.Width, ABitmap.Height);
  ABitmap.Canvas.Brush.Color := clWhite;
  For x := 0 To ABitmap.Width - 1 do
  Begin
    For y := 0 To ABitmap.Height - 1 Do
    Begin
      If Image1.Picture.PNG.Canvas.Pixels[x,y] <> Image1.Picture.PNG.TransparentColor Then
        ABitmap.Canvas.Pixels[x,y] := clWhite;
    end;
  end;
 
  //Image1.Picture.Assign(ABitmap);
  AControl.SetShape(ABitmap);
  ABitmap.Free;
end


Muss ich im Formular noch was spezielles einstellen?
Oder ist der Ansatz schon mal ganz falsch?

Es sollte unter Linux und Windows funktionieren.

Dankeschön, Grüße Markus

Warf
Beiträge: 1426
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: MacOS | Win 10 | Linux
CPU-Target: x86_64
Wohnort: Aachen

Re: Splash Screen transparant?

Beitrag von Warf »

Das FormCreate Event ist zu früh für SetShape, mach die Bitmap als privates Feld, erstell und berechne sie im FormCreate, mach das SetShape im FormShow und das Free dann im Destroy. Dann funktionierts super

MmVisual
Beiträge: 1120
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winux (L 1.6 FPC 3)
CPU-Target: 32/64Bit

Re: Splash Screen transparant?

Beitrag von MmVisual »

Thx, funktioniert!

MmVisual
Beiträge: 1120
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winux (L 1.6 FPC 3)
CPU-Target: 32/64Bit

Re: Splash Screen transparant?

Beitrag von MmVisual »

Hm ... kann man irgendwie ein Bild mit Alpha-Kanal auch darstellen?
Mit SetShape wird nur der Ausschnitt ausgeschnitten, wenn ich jedoch einen Alpha Farbverlauf ins Durchsichtige machen will, wie geht das?
Am besten wäre wenn sich das Formular auf "Durchsichtig" stellt und nur sich das TImage mit dem PNG Bild zeigt.

Der Hintergrund vom Splash-Formular habe ich dunkelblau gemacht damit man sieht wie das Formular ausgeschnitten ist, der Hellgraue Farbverlauf ist im Bild.

Bild1.png
Bild1.png (35.76 KiB) 771 mal betrachtet


EleLa_Verlauf.png
EleLa_Verlauf.png (41.73 KiB) 771 mal betrachtet


Dankeschön, grüße Markus

Warf
Beiträge: 1426
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: MacOS | Win 10 | Linux
CPU-Target: x86_64
Wohnort: Aachen

Re: Splash Screen transparant?

Beitrag von Warf »

Kurze Antwort: Nicht so einfach. Bei Transparenz lieber bei harten kanten bleiben, sonst brauchst du OpenGL o.ä.

Ich hätte aber einen quick and dirty hack der eventuell besser funktionieren könnte. Über die Unit LazIntf kann man sich den Desktop Handle über GetDC(0); holen, dann mit einem Canvas Objekt darauf Zeichnen. Ich weiß nicht wie gut das Transparenz unterstützt und weiß nicht einmal ob das unter Linux geht (unter OSX glaube ich nicht, unter Windows auf jeden Fall), aber das ist schnell gemacht. Muss aber ständig neu gezeichnet werden (z.B. in einem Timer) denn der Hintergrund ändert sich ja stetig. Ist nicht schön, funktioniert aber.

MmVisual
Beiträge: 1120
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winux (L 1.6 FPC 3)
CPU-Target: 32/64Bit

Re: Splash Screen transparant?

Beitrag von MmVisual »

Ich habe gestern Abend einige Stunden damit verbracht was zu finden mit den Lazarus eigenen Mitteln, geht leider nicht. Schade.

Ich muss nur deshalb ein Splash Screen zeigen weil die EXE im Raspberry ca 12 Sekunden braucht bis nur die Steuerelemente erzeugt wurden. Damit man überhaupt was sieht und nicht verzweifelt.
Zusätzlich extra viel Rechenleistung zu verbraten ist nicht wirklich der richtige Weg, daher belasse ich es besser beim "einfachen" Transparent mode.

Dankeschön nochmals!

Mathias
Beiträge: 4855
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunc)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Splash Screen transparant?

Beitrag von Mathias »

Guck dir dies mal an, die sollte sogar mit Bitmap gehen.

http://wiki.freepascal.org/LCL_Tips/de# ... _erstellen
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 4855
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunc)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Splash Screen transparant?

Beitrag von Mathias »

Kurze Antwort: Nicht so einfach. Bei Transparenz lieber bei harten kanten bleiben, sonst brauchst du OpenGL o.ä.

Wie willst du dies mit OpenGL lösen ?

Mit folgendem Befehl, kann ich den Hintergrund nicht transparent machen.

Code: Alles auswählen

  glClearColor(0.0, 0.0, 0.0, 0.0); // Hintergrundfarbe

Ausser in eine Frame/Textur-Buffer, aber diesen muss ich auch auf den BS bringen, und dort gibt ist die Transparent nicht.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

Warf
Beiträge: 1426
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: MacOS | Win 10 | Linux
CPU-Target: x86_64
Wohnort: Aachen

Re: Splash Screen transparant?

Beitrag von Warf »

Mathias hat geschrieben:Wie willst du dies mit OpenGL lösen ?

Mit folgendem Befehl, kann ich den Hintergrund nicht transparent machen.

Code: Alles auswählen

  glClearColor(0.0, 0.0, 0.0, 0.0); // Hintergrundfarbe

Ausser in eine Frame/Textur-Buffer, aber diesen muss ich auch auf den BS bringen, und dort gibt ist die Transparent nicht.


Ja einfach ist auch das nicht, hier ist ein C++ beispiel: https://stackoverflow.com/questions/405 ... background

Hardware beschläunigte frameworks wie .Net WPF oder Delphi FireMonkey können das glaube ich schon mit hausmitteln, sowas gibts für Lazarus aber leider nicht

Mathias
Beiträge: 4855
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunc)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Splash Screen transparant?

Beitrag von Mathias »

Dies habe ich vorhin auch ergoogelt, ist nur win32.

Man müsste es hinkriegen, das der Canvas transparent wird, aber wie ?
Dann würde es auch ohne OpenGL gehen.

Ein ganzes Form, funktioniert, aber dann werden die enthaltenen Komponnenten auch transparent.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

MmVisual
Beiträge: 1120
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winux (L 1.6 FPC 3)
CPU-Target: 32/64Bit

Re: Splash Screen transparant?

Beitrag von MmVisual »

TForm.Color := clNone;

... geht leider auch nicht, denn dann würde es schon genau das sein was ich brauche. Formular ist unsichtbar und das TImage nur noch sichtbar.

MmVisual
Beiträge: 1120
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winux (L 1.6 FPC 3)
CPU-Target: 32/64Bit

Re: Splash Screen transparant?

Beitrag von MmVisual »

Mit dem Splash-Screen braucht EleLa nochmal 8 Sekunden länger zum Starten als ohne beim RaspberryPi :!:
Diese Idee war wohl doch nicht wirklich so toll. :(
Start-Zeit ohne Splash: 19 Sec und mit Splash 27 Sec.

Das einzige wäre wenn ich für den Splash Screen einen separaten Thread mache, vielleicht kann ich dann 2 Kerne nutzen (einer extra für den Splash-Screen). Geht das überhaupt?

Mathias
Beiträge: 4855
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunc)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Splash Screen transparant?

Beitrag von Mathias »

Aber mit einer statischen Form sollte es fast keine Verzögerung geben.

Ich habe sowas in der project.lpr so eingebaut:

Code: Alles auswählen

var
  StartForm: TForm;
 
begin
  StartForm := TForm.CreateNew(nil);
  StartForm.Show;
 
  Application.Title := 'Niveau-Anzeiger';
  RequireDerivedFormResource := True;
  Application.Initialize;
  Application.CreateForm(THauptForm, HauptForm);
  Application.CreateForm(TAnzeigerOptionenForm, AnzeigerOptionenForm);
 
  StartForm.Free;
  Application.Run;
end.

Natürlich muss du noch die StartForm mit dem Images bestücken, am besten dynamisch.
Mit Lazarus sehe ich gün
Mit Java und C/C++ sehe ich rot

MmVisual
Beiträge: 1120
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winux (L 1.6 FPC 3)
CPU-Target: 32/64Bit

Re: Splash Screen transparant?

Beitrag von MmVisual »

Ich kann drehen und machen wie ich will, der Splash kommt auf dem Windows Rechner ohne Verzögerung, der Raspberry braucht 8 Sekunden.
Nach dem "Application.Initialize" braucht es noch ein Application.Progessmessages, denn ansonsten wird das Bild nicht fertig gemalt.

Wenn ich den Splash in einem Thread zeige macht Lazarus es so dass dieser Thread die Windows Messages erhält und der Main App startet erst gar nicht, bzw. das ganze "hängt" sich auf. -> Taskmanager.


Edit: Die 8 Sekunden braucht meine Routine um das Transparent-Masken Bitmap zu errechnen...

Warf
Beiträge: 1426
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: MacOS | Win 10 | Linux
CPU-Target: x86_64
Wohnort: Aachen

Re: Splash Screen transparant?

Beitrag von Warf »

Mathias hat geschrieben:Dies habe ich vorhin auch ergoogelt, ist nur win32.

Man müsste es hinkriegen, das der Canvas transparent wird, aber wie ?
Dann würde es auch ohne OpenGL gehen.

Ein ganzes Form, funktioniert, aber dann werden die enthaltenen Komponnenten auch transparent.


Eine der tieferen Antworten beschreibt auch eine X11 Variante

Antworten