Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Screenshot erstellen und speichern (https://www.delphipraxis.net/75883-screenshot-erstellen-und-speichern.html)

Z32 26. Aug 2006 13:43


Screenshot erstellen und speichern
 
Hallo Wissende,

Ich habe gerade mal eine kurze Frage, habe bei der Suchfunktin nicht das richtige gefunden.

Ich programmiere gerade an einem Programm, dass 25 Screenshots pro Sekunde erstellen soll. Und in ein bestimmtes Verzeichnis speichern soll. Eigentlich ja ganz einfach glaube ich. Doch leider kenne ich den Befehl zum erstellen eines Screenshots nicht. Ich hoffe ihr könnt mir da weiterhelfen.

Zacherl 26. Aug 2006 13:50

Re: Screenshot erstellen und speichern
 
ScreenshotScreenshot :wink:

Der_Unwissende 26. Aug 2006 13:53

Re: Screenshot erstellen und speichern
 
Hi,
auch wenn dir jmd. schon die Lösung rausgesuch hat (und ich mich hier "namentlich" ausgeschlossen fühle), für's nächste Mal (oder ale Erklärung für Florians Ergebnisse), schränke die Suche auf die Code-Lib (Code Bibliothek in der Suche genannt) ein. Da findest du dann fertigen Code!

Gruß Der Unwissende

Z32 26. Aug 2006 14:06

Re: Screenshot erstellen und speichern
 
schon mal vielen Dank, werde ich mir aufjeden Fall angucken... :-D

Z32 26. Aug 2006 14:23

Re: Screenshot erstellen und speichern
 
So habs mir mal angeguckt, hab aber noch ne Frage:

Ich habe mir jetzt eine Prozedure rausgesucht...

Delphi-Quellcode:
procedure ScreenToFile(aFileName: string);
var
  Bitmap: TBitmap;
  Canvas: TCanvas;
begin
  Canvas := TCanvas.Create;
  try
    Canvas.Handle := GetWindowDC(0);
    try
      Bitmap := TBitmap.Create;
      try
        Bitmap.Width := Screen.DesktopWidth;
        Bitmap.Height:= Screen.DesktopHeight;
        Bitmap.PixelFormat := pfDevice;
(* 
        Bitmap.Canvas.CopyRect(Screen.DesktopRect, Canvas, Screen.DesktopRect);

  Anstatt der folgenden Zeile, kann auch die CopyRect Funktion genutzt werden.
  Die CopyRect-Funktion nutzt zusätzlich ein paar Schutzmechanismen, welche für
  ScreenShots nicht notwendig sind. Ausserdem greift die CopyRect-Funktion auf
  StretchBlt-Funktion zurück, welche langsamer als BitBlt ist.
*)
        BitBlt(Bitmap.Canvas.Handle, 0, 0, Pred(Screen.DesktopWidth), Pred( 
            Screen.DesktopHeight), Canvas.Handle, Screen.DesktopLeft,
            Screen.DesktopTop, Bitmap.Canvas.CopyMode);
        Bitmap.SaveToFile(aFileName);
      finally
        Bitmap.Free;
      end;
    finally
      ReleaseDC(0, Canvas.Handle);
    end;
  finally
    Canvas.Free;
  end;
end;
... und rufe die hiermit auf...


Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
screentofile('testscreen');
end;
...aber wo speichert die Anwendung den Screenshot jetzt hin ????


EDIT: Ach habs schon rausgefunden...war mal wieder zu blöd...

Die Aufrufprozedure muss so heißen...

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
screentofile('D:\testscreen.bmp');
end;

MrKnogge 26. Aug 2006 14:26

Re: Screenshot erstellen und speichern
 
Du musst nicht nur einen Namen sondern den ganzen Pfad angeben:

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
screentofile('C:\testscreen.bmp');
end;
gruss

Harry M. 27. Aug 2006 00:40

Re: Screenshot erstellen und speichern
 
http://www.h-soft.info/downloads/sim...een/index.html

DieFliege 10. Okt 2022 09:41

AW: Screenshot erstellen und speichern
 
Hallo Gemeinde,

ja, das Thema ist schon ein paar Tage alt, aber irgendwie stelle ich mich etwas dusselig an.

Ich habe herausgefunden, wie ich einen Screenshot eines ganzen Desktops machen kann, auch kann ich einen Screenshot der aktiven Anwendung machen, allerdings habe ich nicht herausgefunden, wie ich nur einen Teil des Desktops oder einer Anwendung als Screenshot aufnehmen kann. Vielleicht kann mir dazu jemand einen Tipp geben?

Hintergrund: Ich möchte kopierten Text auslesen, diesen in eine Maske aufbereiten und diese Maske soll dann als Screenshot (Grafik) weiter verarbeitet werden.

LG Micha (DieFliege)

himitsu 10. Okt 2022 10:03

AW: Screenshot erstellen und speichern
 
Wieso hat niemand gesagt, wie er den Screenshot macht?

Es gibt tausende Wege.


Zitat:

wie?
Du nimmst deinen ganzen Screenshot und schneidest anschließend das Gewünschte aus? :lol:



Oder du suchst das gewünschte Fenster (HWND) und machst von dessen DC das Foto, anstatt vom DC des Desktops.

DieFliege 10. Okt 2022 10:41

AW: Screenshot erstellen und speichern
 
Zitat:

Zitat von himitsu (Beitrag 1513024)
Wieso hat niemand gesagt, wie er den Screenshot macht?

Ich habe in keinem Wort gefragt "wie" ein Screenshot gemacht wird - Das war mir schon klar ;-)


Zitat:

Zitat von himitsu (Beitrag 1513024)
Du nimmst deinen ganzen Screenshot und schneidest anschließend das Gewünschte aus?

Das hatte ich bisher nicht bedacht, danke für den Tipp!


Zitat:

Zitat von himitsu (Beitrag 1513024)
Oder du suchst das gewünschte Fenster (HWND) und machst von dessen DC das Foto, anstatt vom DC des Desktops.

Genau das war mein eigentlicher Gedanke. Den Schritt, die Grafik zu arbeiten, kommt mir da eher als "Plan B" vor. Mal gucken, was ich zu "DC" finden kann :-)
Vielen Dank erst mal für deine Hilfe!

LG Micha (DieFliege)

himitsu 10. Okt 2022 11:36

AW: Screenshot erstellen und speichern
 
Zitat:

Zitat von DieFliege (Beitrag 1513025)
Ich habe in keinem Wort gefragt "wie" ein Screenshot gemacht wird - Das war mir schon klar ;-)

Ja klar, aber entsprechend dem Wie gibt es auch unterschiedliche Antworten, bezüglich dem "wie weiter" :zwinker:

Bezüglich oben dem GetWindowDC aus der #5 ... ein GetWindowDC bzw. GetDC mit anderem Parameter (Fenster/Canvas):
FindWindow
FindWindowEx
EnumWindows
...
TForm.Handle (HWND)
TForm.Canvas.Handle (HDC)
...

Und bezüglich Delphi-Fenster:
Delphi-Referenz durchsuchenTCustomForm.Print
Delphi-Referenz durchsuchenTCustomForm.GetFormImage
...
TCustomForm.Canvas und Printer.Delphi-Referenz durchsuchenCanvas.Draw
uvm.

Uwe Raabe 10. Okt 2022 11:43

AW: Screenshot erstellen und speichern
 
Vielleicht ist das ja schon anderweitig beschrieben, dann sorry. Ich habe schon seit Jahren folgende Routine im Einsatz, die einen bestimmten Bereich des Desktop in eine Bitmap kopiert:
Delphi-Quellcode:
procedure DesktopScreenShot(DestBitmap: TBitmap; SourceRect: TRect);
var
  DC: HDC;
  wnd: HWND;
begin
  wnd := GetDesktopWindow;
  DC := GetDC(wnd);
  try
    DestBitmap.SetSize(SourceRect.Width, SourceRect.Height);
    BitBlt(DestBitmap.Canvas.Handle, 0, 0, SourceRect.Width, SourceRect.Height, DC, SourceRect.Left, SourceRect.Top, SRCCOPY) ;
  finally
    ReleaseDC(wnd, DC);
  end;
end;

himitsu 10. Okt 2022 11:46

AW: Screenshot erstellen und speichern
 
PS: GetDC(GetDesktopWindow) = GetWindowDC(0), das Desktop=0

wie gesagt, tausende Wege



ganz modern könnte man z.B. auch die DesktopImagingAPI (seit Win 8) benutzen, oder wie die nochmal hieß
die würde dann auch so Dinge ala DirectDraw erwischen, welche sich direkt über die Grafkkarte ins Bild schmuggeln.

Steku 10. Okt 2022 12:27

AW: Screenshot erstellen und speichern
 
Hi,

vielleicht kannst du das mal Testen, oder zum Spicken...

Viele Grüße
Steku

http://www.frontiernet.net/~w2m/apprehend.html

Andreas13 10. Okt 2022 17:28

AW: Screenshot erstellen und speichern
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1513029)
...Ich habe schon seit Jahren folgende Routine im Einsatz, die einen bestimmten Bereich des Desktop in eine Bitmap kopiert:
Delphi-Quellcode:
procedure DesktopScreenShot(DestBitmap: TBitmap; SourceRect: TRect);
var
  DC: HDC;
  wnd: HWND;
begin
  wnd := GetDesktopWindow;
  DC := GetDC(wnd);
  try
    DestBitmap.SetSize(SourceRect.Width, SourceRect.Height);
    BitBlt(DestBitmap.Canvas.Handle, 0, 0, SourceRect.Width, SourceRect.Height, DC, SourceRect.Left, SourceRect.Top, SRCCOPY) ;
  finally
    ReleaseDC(wnd, DC);
  end;
end;

Sind da irgendwelche "neueren" Features dabei Uwe, denn unter XE5 kann ich Deine Routine leider nicht kompilieren:
Delphi-Quellcode:
DestBitmap.SetSize(..)
kennt mein Compiler noch nicht. :(
Grüße, Andreas

Rollo62 10. Okt 2022 17:38

AW: Screenshot erstellen und speichern
 
Hast Du denn Vcl.Graphics in den Uses eingebunden ?
https://docwiki.embarcadero.com/Libr...Bitmap.SetSize
Das sollte es seit "Ewigkeiten" so geben.
Siehe weiter unten bei "VclBitmap: Vcl.Graphics.TBitmap;", das müsste VCL unter XE2 gewesen sein.

Andreas13 10. Okt 2022 18:03

AW: Screenshot erstellen und speichern
 
Ja,
Delphi-Quellcode:
Vcl.Graphics
ist eingebunden. Aber in meiner Unit, wo ich solche nützlichen Routinen sammle, benutzen andere Routinen auch
Delphi-Quellcode:
Winapi.Windows
, und auch dort gibt es ein
Delphi-Quellcode:
SetSize
. Daher kommt der Konflikt.
Wie läßt sich Uwe’s Zeile
Delphi-Quellcode:
DestBitmap.SetSize(SourceRect.Width, SourceRect.Height);
mit qualifizierten Bezeichnern schreiben? Direkt geht es nicht, denn DestBitmap ist der Name des Parameters. Auch mit einer Zwischenvariable habe ich es noch nicht hinbekommen… :oops:
Grüße, Andreas

Andreas13 10. Okt 2022 18:10

AW: Screenshot erstellen und speichern
 
Etwas habe ich noch vergessen: Ich habe in der Uses-Liste auch noch
Delphi-Quellcode:
Vcl.Forms
, und auch dies hat
Delphi-Quellcode:
SetSize
und kann strören.:(

Edit:
Die Fehlermeldung lautet: [dcc32 Fehler]: E2003 Undeklarierter Bezeichner: 'SetSize'

himitsu 10. Okt 2022 18:26

AW: Screenshot erstellen und speichern
 
Nein, weil hier ja nicht mit WITH und so gearbeitet wird und es ja explizit BitmapVariable.SetSize heißt.

Schon DelphiXE kannte ein TBitmap.SetSize (hatte es erst dieses Jahr selbst benutzt)

Rollo62 10. Okt 2022 18:35

AW: Screenshot erstellen und speichern
 
Ich würde die Funktion DesktopScreenShot erstmal in ein eigenes Unit verfrachten, nur mit dem Minimum an Abhängigkeiten,
um das Ganze im ersten Schritt etwas zu modularisieren.
Dieses sollte dann in deinem Unit als Uses eingebunden eigentlich arbeiten können oder vielleicht einen besseren Fehlerhinweis liefern.

Andreas13 10. Okt 2022 18:37

AW: Screenshot erstellen und speichern
 
Inzwischen habe ich alles andere auskommentiert und lediglich die folgenden zwei Units in der Uses-Liste belassen:
Delphi-Quellcode:
Uses
  Vcl.Graphics, Winapi.Windows;
Trotzdem kommt die Fehlermeldung: [dcc32 Fehler]: E2003 Undeklarierter Bezeichner: 'SetSize' :(

Andreas13 10. Okt 2022 18:48

AW: Screenshot erstellen und speichern
 
Könnte bitte jemand folgenden Test mit XE5 kompilieren? :-D
Delphi-Quellcode:
program DesktopScreenShot_Test_1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  Vcl.Graphics,
  Winapi.Windows;


procedure DesktopScreenShot(DestBitmap: TBitmap; SourceRect: TRect);
// https://www.delphipraxis.net/75883-screenshot-erstellen-und-speichern-2.html
// #12: von Uwe Raabe
// 2022-10-10, um 11:43 Uhr

var
  DC: HDC;
  wnd: HWND;
begin
  wnd := GetDesktopWindow;
  DC := GetDC(wnd);
  try
    DestBitmap.SetSize(SourceRect.Width, SourceRect.Height);
    BitBlt(DestBitmap.Canvas.Handle, 0, 0, SourceRect.Width, SourceRect.Height, DC, SourceRect.Left, SourceRect.Top, SRCCOPY) ;
  finally
    ReleaseDC(wnd, DC);
  end;
end;
 
begin
  try

  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
Mein Compiler weigert sich hartnäckig. :cry:

Danke! Grüße, Andreas

Keldorn 10. Okt 2022 19:03

AW: Screenshot erstellen und speichern
 
Hallo

dreh mal die Reihenfolge der units um, zuerst windows und dann graphics.
Tbitmap ist in beiden units definiert

oder du schreibst
Delphi-Quellcode:
procedure DesktopScreenShot(DestBitmap: VCL.Graphics.TBitmap
also VCL.Graphics. ...

Andreas13 10. Okt 2022 19:21

AW: Screenshot erstellen und speichern
 
Danke Keldorn! :thumb:
Mir sind qualifizierte Bezeichner sympathischer:
Delphi-Quellcode:
procedure DesktopScreenShot(DestBitmap: VCL.Graphics.TBitmap; SourceRect: TRect);
, denn die Umkehrung der Reihenfolgde der Units könnte u.U. in anderen Routinen für Chaos sorgen!

Danke Euch allen & Grüße :-D
Andreas

himitsu 10. Okt 2022 19:56

AW: Screenshot erstellen und speichern
 
Kennst du Strg+Linksklick auf "dein" TBitmap?

Zitat:

Delphi-Quellcode:
//unit Winapi.Windows;

{ Bitmap Header Definition }
  PBitmap = ^TBitmap;
  {$EXTERNALSYM tagBITMAP}
  tagBITMAP = record
    bmType: Longint;
    bmWidth: Longint;
    bmHeight: Longint;
    bmWidthBytes: Longint;
    bmPlanes: Word;
    bmBitsPixel: Word;
    bmBits: Pointer;
  end;
  TBitmap = tagBITMAP;
  {$EXTERNALSYM TBitmap}
  BITMAP = tagBITMAP;
  {$EXTERNALSYM BITMAP}

Wer/wann ist, um Himmels Willen, da denn auf diese saudämliche strunzdoofe Idee gekommen?

Warum ausgerechnet HIER dieser "Pascalname", in der WinAPI,
und wenn, warum dann nicht TBitmapHeader.


Ist ja fast so ein Schwachsinn, wie das mit den beiden TMonitor. :wall:


Lösung 1:
Delphi-Quellcode:
uses
  Winapi.Windows;
  System.SysUtils,
  Vcl.Graphics, // Windows vor Graphics
Lösung 2:
Delphi-Quellcode:
procedure DesktopScreenShot(DestBitmap: Vcl.Graphics.TBitmap; SourceRect: TRect);

himitsu 10. Okt 2022 20:17

AW: Screenshot erstellen und speichern
 
Es ist einfach nur trauchig.

https://quality.embarcadero.com/browse/RSP-21364


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:35 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz