Screenshot einer nicht sichtbaren Form erzeugen

Für Probleme bezüglich Grafik, Audio, GL, ACS, ...
ArchChem
Beiträge: 82
Registriert: Mo 11. Jul 2022, 10:41

Re: Screenshot einer nicht sichtbaren Form erzeugen

Beitrag von ArchChem »

Hallo allerseits,

danke für eure Antworten!
kupferstecher hat geschrieben:
Sa 20. Mai 2023, 11:54
Es gibt schon Möglichkeiten, z.B. mit TWinControl.PaintTo. Allerdings geht das so viel ich weiß unter Linux nicht mit dem GTK-Widgetset (dort dann schwarz, was nicht auch auf dem Bildschirm sichtbar ist), sondern nur mit QT. Windows funktioniert auch. Auch über LM_Paint und BitBLT lässt sich was machen, jede Variante hat so ihre Eigenheit, also einfach ausprobieren.
Danke dir, Kupferstecher! Leider hat bei mir unter Linux+Qt5 keine der drei Ansätze funktioniert. Mein Code sieht so:

Code: Alles auswählen

PreviewPresentationForm.FormShow(frmSettings);
PreviewPresentationForm.ResizeBackground;
PreviewPresentationForm.Color:=clPurple; // um zu testen, ob die Form erfolgreich dargestellt wird
PreviewPresentationForm.Repaint;
PreviewPresentationForm.Refresh;
PreviewPresentationForm.Update;
PreviewPresentationForm.Invalidate;
PreviewPresentationForm.Canvas.Refresh;
PreviewPresentationForm.PaintTo(ImagePresentationPreview.Canvas, 0, 0); // bzw. die zwei anderen Ansätze
Habe ich da vielleicht etwas übersehen?
KodeZwerg hat geschrieben:
Sa 20. Mai 2023, 12:37
Ich habs noch nicht so ganz verstanden aber hier wäre eine möglichkeit unter windows:
Danke für den Tipp! Das funktioniert natürlich auch gut, auch wenn die Form trotzdem angezeigt wird...

Benutzeravatar
KodeZwerg
Beiträge: 94
Registriert: Mo 6. Feb 2023, 11:04

Re: Screenshot einer nicht sichtbaren Form erzeugen

Beitrag von KodeZwerg »

ArchChem hat geschrieben:
Sa 20. Mai 2023, 22:22
KodeZwerg hat geschrieben:
Sa 20. Mai 2023, 12:37
Ich habs noch nicht so ganz verstanden aber hier wäre eine möglichkeit unter windows:
Danke für den Tipp! Das funktioniert natürlich auch gut, auch wenn die Form trotzdem angezeigt wird...
Gern geschehen. Also AlphaBlendValue auf Stärke 1 ist bei mir (Windows) praktisch unsichtbar, zeige mir mal unter Linux was da passiert.
Zuletzt geändert von KodeZwerg am Sa 39. Okt 6043, 29:87, insgesamt 43-mal geändert.

wennerer
Beiträge: 507
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Re: Screenshot einer nicht sichtbaren Form erzeugen

Beitrag von wennerer »

Hallo ArchChem,
falls du Lust hast kannst du mal mein angehängtes Projekt testen. Würde mich interessieren ob das bei dir läuft.

Viele Grüße
Bernd
Dateianhänge
project1.zip
(109.96 KiB) 28-mal heruntergeladen

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

Re: Screenshot einer nicht sichtbaren Form erzeugen

Beitrag von Mathias »

Hallo ArchChem,
falls du Lust hast kannst du mal mein angehängtes Projekt testen. Würde mich interessieren ob das bei dir läuft.
Ich habe es getestet.
Unter Linux perfekt.
Mit Windows verwaschen, aber dies könnte auch an Wine liegen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wennerer
Beiträge: 507
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Re: Screenshot einer nicht sichtbaren Form erzeugen

Beitrag von wennerer »

Hallo Matthias,
danke fürs testen. Liegt nicht an Wine. Linux und Windows verrechnen die Titelleiste unterschiedlich. Hab ich vergessen. Habe es nun angepasst.

Code: Alles auswählen

unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,Clipbrd, ExtCtrls, unit2;

type

  { TForm1 }

  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click({%H-}Sender: TObject);
    procedure Button2Click({%H-}Sender: TObject);
    procedure CheckActive({%H-}Sender: TObject);
    procedure FormClose({%H-}Sender: TObject; var {%H-}CloseAction: TCloseAction);
    procedure FormCreate({%H-}Sender: TObject);
    procedure FormPaint({%H-}Sender: TObject);
  private
    aTimer  : TTimer;
    clp     : boolean;
  public
    Form2BMP  : TBitmap;
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
 Form2.Show;
 clp := false;
 aTimer.Enabled := true;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 Form2.Show;
 clp := true;
 aTimer.Enabled := true;
end;

procedure TForm1.CheckActive(Sender: TObject);
var aBmp : TBitmap;
begin
 if Form2.Active then
  begin
   aTimer.Enabled := false;
   Form2BMP.SetSize(Form2.Width,Form2.Height);
   if not clp then
    begin
    {$IFDEF WINDOWS}
     Form2BMP.Canvas.CopyRect(rect(0,0,Form2.Width,Form2.Height),Form2.Canvas,rect(0,0,Form2.Width,Form2.Height));
    {$ENDIF}
    {$IFDEF Linux}
     Form2.PaintTo(Form2Bmp.Canvas,0,0);
    {$ENDIF}
     Form2.Close;
     Form1.Invalidate;
    end;
   if clp then
    begin
     aBmp   := TBitmap.Create;
     try
      aBmp.SetSize(Form2.Width,Form2.Height);

     {$IFDEF WINDOWS}
      aBmp.Canvas.CopyRect(rect(0,0,Form2.Width,Form2.Height),Form2.Canvas,rect(0,0,Form2.Width,Form2.Height));
     {$ENDIF}
    {$IFDEF Linux}
     Form2.PaintTo(aBmp.Canvas,0,0);
    {$ENDIF}
      Clipboard.Assign(aBmp);
      Form2.Close;
     finally
      aBmp.Free;
     end;//try
    end;
   end;//active
end;

procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
 Form2BMP.Free;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 Form2BMP                    := TBitmap.Create;
 Form2BMP.SetSize(500,200);
 Form2BMP.Canvas.Brush.Color := clWhite;
 Form2BMP.Canvas.FillRect(0,0,500,200);

 aTimer          := TTimer.Create(self);
 aTimer.Enabled  := false;
 aTimer.Interval := 100;
 aTimer.OnTimer  := @CheckActive;
end;

procedure TForm1.FormPaint(Sender: TObject);
begin
 canvas.Draw(10,10,Form2BMP);
end;

end.
Dateianhänge
project1.zip
(110.1 KiB) 31-mal heruntergeladen

ArchChem
Beiträge: 82
Registriert: Mo 11. Jul 2022, 10:41

Re: Screenshot einer nicht sichtbaren Form erzeugen

Beitrag von ArchChem »

Hallo allerseits,

danke für eure Antworten und die anregende Diskussion!
wennerer hat geschrieben:
So 21. Mai 2023, 08:22
falls du Lust hast kannst du mal mein angehängtes Projekt testen. Würde mich interessieren ob das bei dir läuft.
Danke für das Projekt! Das funktioniert bei mir. Allerdings wird die Form dazu kurz sichtbar (was ja auch aus dem Quelltext hervorgeht). Mein Ziel ist es, einen Screenshot der Form zu erstellen, ohne diese sichtbar werden zu lassen. Das scheint allerdings tatsächlich nicht möglich zu sein, da das Canvas der Form erst dann gezeichnet wird, wenn sie sichtbar wird.

Aus diesem Grund werde ich mein Projekt nochmal umbauen und statt auf Form-Komponenten zurückzugreifen alles direkt auf ein Bitmap zeichnen. Trotzdem danke euch!

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

Re: Screenshot einer nicht sichtbaren Form erzeugen

Beitrag von Mathias »

Danke für das Projekt! Das funktioniert bei mir. Allerdings wird die Form dazu kurz sichtbar (was ja auch aus dem Quelltext hervorgeht). Mein Ziel ist es, einen Screenshot der Form zu erstellen, ohne diese sichtbar werden zu lassen.
Und jetzt noch den Alphablening einschalten, dann sollte es kaum mehr sichtbar sein.

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
begin
 Form2.AlphaBlend:=True;
 form2.AlphaBlendValue:=1;
 Form2.Show;
Auch ohne diesen Code, ich sehe, das Form2 gar nicht, oder liegt dies an Linux ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
kupferstecher
Beiträge: 418
Registriert: Do 17. Nov 2016, 11:52

Re: Screenshot einer nicht sichtbaren Form erzeugen

Beitrag von kupferstecher »

ArchChem hat geschrieben:
Mo 22. Mai 2023, 09:03
Das funktioniert bei mir. Allerdings wird die Form dazu kurz sichtbar (was ja auch aus dem Quelltext hervorgeht). Mein Ziel ist es, einen Screenshot der Form zu erstellen, ohne diese sichtbar werden zu lassen. Das scheint allerdings tatsächlich nicht möglich zu sein, da das Canvas der Form erst dann gezeichnet wird, wenn sie sichtbar wird.
Ich denke es liegt am Erzeugen der Form.
Du könntest dein Formularinhalt auf ein Panel zu bringen, das du dann im Formular der Anwendung plazierst, ohne es anzuzeigen. Oder mit einem Frame arbeiten. Jedenfalls müssen bei PaintTo unter Win und Linux/Qt die Komponenten nicht sichtbar sein.

wennerer
Beiträge: 507
Registriert: Di 19. Mai 2015, 20:05
OS, Lazarus, FPC: Linux Mint 20 Cinnamon,Lazarus 2.2.6 (rev lazarus_2_2_6) FPC 3.2.2 x86_64-linux-
CPU-Target: x86_64-linux-gtk2

Re: Screenshot einer nicht sichtbaren Form erzeugen

Beitrag von wennerer »

Hallo,
also ich habe mir meinen Anhang (den 2.) eben nochmal herunter geladen und angeschaut. Da steht im OI der Form2:
Alpha.png
Alpha.png (32.43 KiB) 679 mal betrachtet
Ich kann mir beim besten Willen nicht vorstellen das die zweite Form sichtbar ist. Allenfalls kann das kopieren nicht funktionieren.
Eventuell hat ArchChem den Code kopiert und in ein eigenes Projekt kopiert?

Viele Grüße
Bernd

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

Re: Screenshot einer nicht sichtbaren Form erzeugen

Beitrag von Mathias »

Ich kann mir beim besten Willen nicht vorstellen das die zweite Form sichtbar ist. Allenfalls kann das kopieren nicht funktionieren.
Hier wird es kurz sichtbar gemacht, ausser Alpha macht es durchsichtig, somit wäre in diesem kurzen Moment ein Klicken ins Form2 möglich.
Aber eben, es geht so schnell, da merkt man dies nicht.

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
begin
 Form2.Show;
 clp := false;
 aTimer.Enabled := true;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 Form2.Show;
 clp := true;
 aTimer.Enabled := true;
end;
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

ArchChem
Beiträge: 82
Registriert: Mo 11. Jul 2022, 10:41

Re: Screenshot einer nicht sichtbaren Form erzeugen

Beitrag von ArchChem »

Hallo Bernd,
wennerer hat geschrieben:
Mo 22. Mai 2023, 17:13
Ich kann mir beim besten Willen nicht vorstellen das die zweite Form sichtbar ist. Allenfalls kann das kopieren nicht funktionieren.
Eventuell hat ArchChem den Code kopiert und in ein eigenes Projekt kopiert?
Ja genau, das ist auch bei mir so – und wahrscheinlich für die meisten Anwendungsfälle vollkommen ausreichend. In meinem Fall allerdings habe ich ein Präsentationsprogramm, bei welchem ich die Präsentationsfolien (welche bisher aus LCL-Komponenten erstellt wurden) OHNE Anzeige eines Forms als Bitmap haben möchte. Man denke beispielsweise an eine Exportfunktion, bei welcher alle Folien jeweils als Bilddatei gespeichert werden sollten (und eventuell ohne X-Server von der Kommandozeile aus). Da ist es wichtig, dass das Bild ohne Anzeige einer Form generiert werden kann.

Trotzdem vielen Dank für die Ansätze, welche bestimmt für die meisten Anwendungsfälle hervorragend geeignet sind!

Antworten