Screenshots machen
Screenshots machen
Hallo! Bitte verzeiht meine n00b-Frage. Ich steige gerade erst von Delphi auf Lazarus/FreePascal um.
Ich möchte eigentlich sehr simpel einen Screenshot machen eines Teils des Bildschirms und den in ein TBitmap kopieren.
Leider findet "Screenshot", "Screenshot machen" und "take screenshot" in Suchmaschinen und auch hier in der Forumsuche zu viel andere Themen, selbst wenn ich "Free Pascal" oder "freepascal" mit angebe. =) Eine Forumsuche nach "Screenshot" nur im Betreff ergab keine Treffer.
Wie stell ichs am besten an?
Euer Sven
PS: Ich benutze Lazarus 0.9.26.2 Beta mit FreePascal 2.2.2 auf Windows XP.
Ich möchte eigentlich sehr simpel einen Screenshot machen eines Teils des Bildschirms und den in ein TBitmap kopieren.
Leider findet "Screenshot", "Screenshot machen" und "take screenshot" in Suchmaschinen und auch hier in der Forumsuche zu viel andere Themen, selbst wenn ich "Free Pascal" oder "freepascal" mit angebe. =) Eine Forumsuche nach "Screenshot" nur im Betreff ergab keine Treffer.
Wie stell ichs am besten an?
Euer Sven
PS: Ich benutze Lazarus 0.9.26.2 Beta mit FreePascal 2.2.2 auf Windows XP.
-
- Beiträge: 688
- Registriert: Mi 3. Okt 2007, 21:00
- OS, Lazarus, FPC: Linux (L 0.9.29 FPC 2.4.2)
- CPU-Target: x86_64
Re: Screenshots machen
Hallo Sven, Willkommen im Forum
!
Windows oder Linux? Unter Linux kannst du ein Hilfsprogramm des X-Windows-System nutzen.
P.S: Ups, doch Windows
Habe ich überlesen.
Funktioniert folgender Code bei dir?

Windows oder Linux? Unter Linux kannst du ein Hilfsprogramm des X-Windows-System nutzen.
P.S: Ups, doch Windows

Funktioniert folgender Code bei dir?
Code: Alles auswählen
var
bmp: TBitmap;
ScreenDC: HDC;
begin
bmp := TBitmap.Create;
ScreenDC := GetDC(0);
bmp.LoadFromDevice(ScreenDC);
ReleaseDC(ScreenDC);
bmp.SaveToFile('screenshot-1.bmp');
bmp.Free;
end;
Zuletzt geändert von Targion am Di 19. Mai 2009, 12:45, insgesamt 1-mal geändert.
Re: Screenshots machen
danke für die schnelle Antwort.
ich habe unten noch
eingefügt auf Verdacht, und oben
, damit er HDC und GetDC findet. Jetzt ist der nächste verbleibende Fehler, dass er keine Methode "Create" für TBitmap findet. 
"Graphics" ist schon in der uses-Klausel enthalten.
Edit: Das war in einem Formular als OnClick-Event. Ich versuchs mal in einem ganz neuen Programm.
Edit 2: jetzt bin ich noch mehr verwirrt. im neuen Programm wirft schon das "Graphics" in der uses-Klausel den Fehler "scrshot.lpr(9,6) Fatal: Can't find unit Graphics used by scrshot"

Code: Alles auswählen
MyBitmap.SaveToFile('test.bmp');
MyBitmap.Free;
Code: Alles auswählen
uses Windows;

"Graphics" ist schon in der uses-Klausel enthalten.
Edit: Das war in einem Formular als OnClick-Event. Ich versuchs mal in einem ganz neuen Programm.
Edit 2: jetzt bin ich noch mehr verwirrt. im neuen Programm wirft schon das "Graphics" in der uses-Klausel den Fehler "scrshot.lpr(9,6) Fatal: Can't find unit Graphics used by scrshot"
-
- Beiträge: 688
- Registriert: Mi 3. Okt 2007, 21:00
- OS, Lazarus, FPC: Linux (L 0.9.29 FPC 2.4.2)
- CPU-Target: x86_64
Re: Screenshots machen
Sind alle Pfade korrekt gesetzt? (Also die Pfade zum Lazarus-Ordner usw.?) Ansonsten kannst du diese Über die Compileroptionen auch manuell einfügen.
-
- Lazarusforum e. V.
- Beiträge: 2809
- Registriert: Sa 9. Sep 2006, 18:05
- OS, Lazarus, FPC: Linux (L trunk FPC trunk)
- CPU-Target: 64Bit
- Wohnort: Dresden
- Kontaktdaten:
Re: Screenshots machen
Hast du im Projectinspektor bei benötigte Packages auch die LCL stehen? Wenn nicht, musst du die noch als Abhängigkeit hinzufügen, dann sollte er graphics finden, da das Teil der LCL ist.
Ansonsten würde ich den Code von Targion auf ein TPicture statt TBitmap setzen, dann kannst du auch in anderen Formaten speichern.
Der Code von oben funktioniert bei mir bestens. Das einzige, was zu beachten ist, es wird nur der Hauptmonitor gespeichert, sollte man mehrere dran haben.
Ansonsten würde ich den Code von Targion auf ein TPicture statt TBitmap setzen, dann kannst du auch in anderen Formaten speichern.
Code: Alles auswählen
procedure TForm1.Button1Click(Sender: TObject);
var
MyBitmap: TPicture;
ScreenDC: HDC;
begin
MyBitmap := TPicture.Create;
try
ScreenDC := GetDC(0);
MyBitmap.Bitmap.LoadFromDevice(ScreenDC);
ReleaseDC(0, ScreenDC);
MyBitmap.Bitmap.SaveToFile('Test.bmp');
finally
MyBitmap.Free;
end;
end;
Zuletzt geändert von monta am Di 19. Mai 2009, 22:45, insgesamt 1-mal geändert.
Grund: Parameterreihenfolge korrigiert.
Grund: Parameterreihenfolge korrigiert.
Johannes
Re: Screenshots machen
danke für eure Tipps. mit LCL als Abhängigkeit hat er "Graphics" gefunden.
Screenshoten klappt jetzt auch.
allerdings wird der Bereich, den ich screenshoten will, später im echten Einsatz auf dem Sekundärmonitor liegen. =)
und der Bereich ist eigentlich nur eine sehr kleine Linie (ca. 1x50 Pixel) im Vergleich zur Bildschirmauflösung (1280x800 oder mehr). muss ich wirklich alle Pixel in mein Bitmap kopieren? ich weiß, PCs sind heutezutage schnell und haben viel Speicher, aber es fühlt sich falsch an.
wenn ichs recht überlege, muss es nichtmal wirklich gespeichert werden. es würde reichen, wenn ich der Reihe nach die Farbwerte der Pixel abfragen kann. das Programm soll ein anderes (closed source
) Programm überwachen und Befehle ausführen, je nachdem, wie die Buttons da ihre Farbe wechseln. 
Screenshoten klappt jetzt auch.
allerdings wird der Bereich, den ich screenshoten will, später im echten Einsatz auf dem Sekundärmonitor liegen. =)
und der Bereich ist eigentlich nur eine sehr kleine Linie (ca. 1x50 Pixel) im Vergleich zur Bildschirmauflösung (1280x800 oder mehr). muss ich wirklich alle Pixel in mein Bitmap kopieren? ich weiß, PCs sind heutezutage schnell und haben viel Speicher, aber es fühlt sich falsch an.

wenn ichs recht überlege, muss es nichtmal wirklich gespeichert werden. es würde reichen, wenn ich der Reihe nach die Farbwerte der Pixel abfragen kann. das Programm soll ein anderes (closed source


-
- Lazarusforum e. V.
- Beiträge: 2809
- Registriert: Sa 9. Sep 2006, 18:05
- OS, Lazarus, FPC: Linux (L trunk FPC trunk)
- CPU-Target: 64Bit
- Wohnort: Dresden
- Kontaktdaten:
Re: Screenshots machen
Das ist ja nen eigenartiges Programm, wo es nach Buttonfarbe geht 
Hab gerade mal gestöbert:
http://msdn.microsoft.com/en-us/library/aa928105.aspx" onclick="window.open(this.href);return false;
Kannst eigentlich ganz einfach Pixel direkt abfragen:
Musst halt nur irgendwie dafür sorgen, die richtigen Pixel zu erwischen.
Bildschirmausschnitte würdest du damit bekommen:
http://msdn.microsoft.com/en-us/library/aa930997.aspx" onclick="window.open(this.href);return false;

Hab gerade mal gestöbert:
http://msdn.microsoft.com/en-us/library/aa928105.aspx" onclick="window.open(this.href);return false;
Kannst eigentlich ganz einfach Pixel direkt abfragen:
Code: Alles auswählen
procedure TForm1.Button2Click(Sender: TObject);
var
ScreenDC: HDC;
RGB: integer;
begin
ScreenDC := GetDC(0);
RGB := GetPixel(ScreenDC, 10, 10);
ShowMessage(IntToStr(GetRValue(RGB)) + ' - ' + IntToStr(GetGValue(RGB)) +
' - ' + IntToStr(GetBValue(RGB)));
end;
Bildschirmausschnitte würdest du damit bekommen:
http://msdn.microsoft.com/en-us/library/aa930997.aspx" onclick="window.open(this.href);return false;
Johannes
Re: Screenshots machen
perfekt, danke! das funktioniert mit passenden Koordinaten sogar auf dem 2. Bildschirm. 
ich hab trotzdem mal noch "ReleaseDC(0, ScreenDC);" (<-- korrigiert) eingebaut.
Update 19.05.2009: Die Parameter für ReleaseDC müssen umgekehrt sein: Erst die Nummer, die man auch für GetDC benutzt hat, und dann das Handle, dass man von GetDC bekommen hat. Vor dieser Korrektur hat mein Programm den ganzen RAM leergefressen, weil es bei jedem GetDC 4 KB Speicher mehr angefordert und den nicht wieder freigegeben hat. Ich prüfe jetzt auch die Rückgabewerte von GetDC und ReleaseDC auf Fehler, gemäß der Dokumentation auf http://msdn.microsoft.com/en-us/library/aa923590.aspx" onclick="window.open(this.href);return false; (MSDN Library: GDI Functions).

ich hab trotzdem mal noch "ReleaseDC(0, ScreenDC);" (<-- korrigiert) eingebaut.
Update 19.05.2009: Die Parameter für ReleaseDC müssen umgekehrt sein: Erst die Nummer, die man auch für GetDC benutzt hat, und dann das Handle, dass man von GetDC bekommen hat. Vor dieser Korrektur hat mein Programm den ganzen RAM leergefressen, weil es bei jedem GetDC 4 KB Speicher mehr angefordert und den nicht wieder freigegeben hat. Ich prüfe jetzt auch die Rückgabewerte von GetDC und ReleaseDC auf Fehler, gemäß der Dokumentation auf http://msdn.microsoft.com/en-us/library/aa923590.aspx" onclick="window.open(this.href);return false; (MSDN Library: GDI Functions).