Screenshots machen

Für Probleme bezüglich Grafik, Audio, GL, ACS, ...
Antworten
Sven
Beiträge: 6
Registriert: So 17. Mai 2009, 21:31

Screenshots machen

Beitrag von Sven »

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.

Targion
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

Beitrag von Targion »

Hallo Sven, Willkommen im Forum :mrgreen: !
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?

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.

Sven
Beiträge: 6
Registriert: So 17. Mai 2009, 21:31

Re: Screenshots machen

Beitrag von Sven »

danke für die schnelle Antwort. :mrgreen: ich habe unten noch

Code: Alles auswählen

MyBitmap.SaveToFile('test.bmp');
  MyBitmap.Free;
eingefügt auf Verdacht, und oben

Code: Alles auswählen

uses Windows;
, damit er HDC und GetDC findet. Jetzt ist der nächste verbleibende Fehler, dass er keine Methode "Create" für TBitmap findet. :shock:
"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"

Targion
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

Beitrag von Targion »

Sind alle Pfade korrekt gesetzt? (Also die Pfade zum Lazarus-Ordner usw.?) Ansonsten kannst du diese Über die Compileroptionen auch manuell einfügen.

monta
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

Beitrag von monta »

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.

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;
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.
Zuletzt geändert von monta am Di 19. Mai 2009, 22:45, insgesamt 1-mal geändert.
Grund: Parameterreihenfolge korrigiert.
Johannes

Sven
Beiträge: 6
Registriert: So 17. Mai 2009, 21:31

Re: Screenshots machen

Beitrag von Sven »

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. :oops:

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. :)

monta
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

Beitrag von monta »

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:

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;
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;
Johannes

Sven
Beiträge: 6
Registriert: So 17. Mai 2009, 21:31

Re: Screenshots machen

Beitrag von Sven »

perfekt, danke! das funktioniert mit passenden Koordinaten sogar auf dem 2. Bildschirm. :D
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).

monta
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

Beitrag von monta »

Ich hab es oben nun auch korrigiert.
Johannes

Antworten