Zrzut ekranu

edytuj

Za Wiki:

Zrzut ekranu (z ang. screenshot, screen dump, screen capture) czyli zapis aktualnego obrazu wyświetlanego na monitorze, najczęściej do pliku graficznego.

Zrzuty ekranu stosuje się np. w celu demonstracji oprogramowania lub problemu użytkownika, umieszczenia ich w instrukcji lub w dowolnym innym przypadku, gdy z pewnego powodu zachodzi potrzeba pokazania zarchiwizowanej zawartości ekranu innym.

Bywa również czasem używany, w celu wydrukowania zawartości któregoś z okien, gdy programista nie przewidział możliwości użycia drukarki (a więc np. w celu ominięcia ograniczenia wydruku).

AutoIt posiada zestaw 7 funkcji umożliwiających zrzut całego ekranu, jego fragmentów lub poszczególnych okien. Funkcje te zawarte są w pliku "ScreenCapture.au3", do ich prawidłowego działania niezbędna jest także obecność bibliotek "GDIPlus.au3" i "WinAPI.au3".


_ScreenCapture_Capture

edytuj
#include <ScreenCapture.au3>
_ScreenCapture_Capture([$sFileName = "" [, $iLeft = 0 [, $iTop = 0 [, $iRight = -1 [, $iBottom = -1 [, $fCursor = True]]]]]])

Funkcja zapisuje na dysku (lub w pamięci) plik graficzny ze zrzutem ekranu. Jeżeli nie podamy nazwy pliku to funkcja zwraca uchwyt do utworzonej w pamięci bitmapy (HBITMAP), w przeciwnym razie nie zwraca nic.

Wszystkie parametry są opcjonalne.

$sFileName - nazwa pliku obrazu z pełną ścieżką i rozszerzeniem

$iLeft i $iTop - współrzędna lewego górnego rogu prostokąta zrzucanego obszaru

$iRight i $iBottom - współrzędne prawego dolnego rogu prostokąta zrzucanego obszaru, -1 oznacza max. wymiar bieżącego ekranu

$fCursor - TRUE - obraz łącznie z kursorem, FALSE - obraz bez kursora

UWAGA: Funkcja ustala format zapisu obrazu na podstawie rozszerzenie nazwy pliku. Dostępne są rozszerzenia: BMP, GIF, JPEG, PNG i TIF.

Niestety funkcja nie działa prawidłowo gdy system używa do rysowania okien procesora graficznego (np. Windows 7).

Przykład:

 
#include <ScreenCapture.au3>

;zrzut całego ekranu
_ScreenCapture_Capture("zrzut_1.jpg")

;zrzut fragmentu ekranu
_ScreenCapture_Capture("zrzut_2.jpg", 0, 0, 796, 596)


_ScreenCapture_CaptureWnd

edytuj
#include <ScreenCapture.au3>
_ScreenCapture_CaptureWnd($sFileName, $hWnd [, $iLeft = 0 [, $iTop = 0 [, $iRight = -1 [, $iBottom = -1 [, $fCursor = True]]]]])

Funkcja zapisuje na dysku (lub w pamięci) plik graficzny ze zrzutem okna. Jeżeli podamy nazwy pliku jako "", to funkcja zwraca uchwyt do utworzonej w pamięci bitmapy (HBITMAP), w przeciwnym razie nie zwraca nic.

$sFileName - nazwa pliku obrazu z pełną ścieżką i rozszerzeniem

$hWnd - uchwyt do okna

Pozostałe parametry opcjonalne.

$iLeft i $iTop - współrzędna lewego górnego rogu prostokąta zrzucanego obszaru

$iRight i $iBottom - współrzędne prawego dolnego rogu prostokąta zrzucanego obszaru, -1 oznacza max. wymiar bieżącego ekranu

$fCursor - TRUE - obraz łącznie z kursorem, FALSE - obraz bez kursora

UWAGA:

1. Wszystkie współrzędne względem wybranego okna.

2. Funkcja ustala format zapisu obrazu na podstawie rozszerzenie nazwy pliku. Dostępne są rozszerzenia: BMP, GIF, JPEG, PNG i TIF.

Niestety funkcja nie działa prawidłowo gdy system używa do rysowania okien procesora graficznego (np. Windows 7).


_ScreenCapture_SaveImage

edytuj
#include <ScreenCapture.au3>
_ScreenCapture_SaveImage($sFileName, $hBitmap [, $fFreeBmp = True])

Funkcja zapisuje bitmapę z pamięci na dysk. Zwraca TRUE gdy sukces, lub FALSE gdy wystąpił błąd.

$sFileName - nazwa pliku obrazu z pełną ścieżką i rozszerzeniem

$hBitmap - uchwyt HBITMAP do bitmapy

$fFreeBmp - jeżeli TRUE, to uchwyt zostanie zwolniony po udanym zapisie na dysk

UWAGA: Funkcja ustala format zapisu obrazu na podstawie rozszerzenie nazwy pliku. Dostępne są rozszerzenia: BMP, GIF, JPEG, PNG i TIF.

Przykład:

 
#include <ScreenCapture.au3>

;zrzut ekranu do pamięci
$hBmp = _ScreenCapture_Capture("")

;zapis obrazu na dusku
_ScreenCapture_SaveImage("zrzut_1.jpg", $hBmp)


_ScreenCapture_SetBMPFormat

edytuj
#include <ScreenCapture.au3>
_ScreenCapture_SetBMPFormat($iFormat)

Funkcja ustala format bitmapy dla zrzucanego ekranu. Nie zwraca żadnej wartości.

$iFormat - kod formatu

Bitów na piksel obrazu (bpp):
0 = 16 bpp; 5 bitów dla każdej składowej RGB
1 = 16 bpp, 5 bitów dla czerwonego, 6 bitów dla zielonego i 5 bitów dla niebieskiego
2 = 24 bpp, 8 bitów dla każdej składowej RGB
3 = 32 bpp, 8 bitów dla każdej składowej RGB, bez stopnia przezroczystości 
4 = 32 bpp, 8 bitów dla każdej składowej RGB, ze stopniem przezroczystości (kanał alfa)

Przykład:

 
#include <ScreenCapture.au3>

;ustalenie formatu obrazu 
_ScreenCapture_SetBMPFormat(0)

;zrzut ekranu w ustalonym formacie
_ScreenCapture_Capture("zrzut_1.bmp")


_ScreenCapture_SetJPGQuality

edytuj
#include <ScreenCapture.au3>
_ScreenCapture_SetJPGQuality($iQuality)

Funkcja ustala poziom jakości obrazu dla zrzutów w formacie JPG. Nie zwraca żadnej wartości.

$iQuality - poziom jakości obrazu, 100 - najwyższy (plik największy), 0 - najniższy (plik najmniejszy)

UWAGA: Jeżeli nie użyjemy tej funkcji, to domyślnym poziomem jest 100.

Przykład:

 
#include <ScreenCapture.au3>

;ustalenie poziomu jakości
_ScreenCapture_SetJPGQuality(50)

;zrzut całego ekranu
_ScreenCapture_Capture("zrzut_50.jpg")

_ScreenCapture_SetTIFColorDepth

edytuj
#include <ScreenCapture.au3>
_ScreenCapture_SetTIFColorDepth($iDepth)

Funkcja ustala głębię kolorów dla zrzutów w formacie TIFF. Nie zwraca żadnej wartości.

$iDepth - głębia kolorów, 0 - domyślna enkodera, 24 - 24 bitowa, 32 - 32 bitowa

UWAGA: Jeżeli nie użyjemy tej funkcji, to domyślną głębią będzie 24.


_ScreenCapture_SetTIFCompression

edytuj
#include <ScreenCapture.au3>
_ScreenCapture_SetTIFCompression($iCompress)

Funkcja ustala sposób kompresji obrazu dla zrzutów w formacie TIFF. Nie zwraca żadnej wartości.

$iCompress - sposób kompresji, 0 - domyślna enkodera, 1 - bez kompresji, 2 - kompresja LZW

UWAGA: Jeżeli nie użyjemy tej funkcji, to domyślną kompresją jest LZW.

Przykład:

 
#include <ScreenCapture.au3>

;ustalenie głębi kolorów (32 bity)
_ScreenCapture_SetTIFColorDepth(32)

;ustalenie sposobu kompresji (bez kompresji)
_ScreenCapture_SetTIFCompression(1)

;zrzut całego ekranu
_ScreenCapture_Capture("zrzut_50.tif")


Uzupełnienie

edytuj

Ponieważ funkcje _ScreenCapture_Capture i _ScreenCapture_CaptureWnd nie działają prawidłowo gdy system używa do rysowania okien procesora graficznego, nie pozostaje nic innego jak użyć innej, zmodyfikowanej funkcji pozbawionej tych wad.

Poniżej przedstawiam zmodyfikowaną przeze mnie funkcję _ScreenCapturePlus, która łączy działanie obu powyższych (plus dodatkowa możliwość zrzucenie tylko przestrzeni roboczej okna).


_ScreenCapturePlus

edytuj
#include <GDIPlus.au3>
_ScreenCapturePlus( [$file = "" [, $hWnd = -1 [, $left = -1 [, $top = -1 [, $w = -1 [, $h = -1 [, $Cursor = True [, $frame = 4]]]]]]]])

Funkcja zapisuje na dysku lub zwraca uchwyt do zrzutu ekranu. Można zrzucić cały ekran lub jego fragment, okno, jego fragment lub tylko przestrzeń roboczą. Funkcja do działania wymaga biblioteki GDIPlus.au3.

$file - nazwa pliku do zapisania obrazu, jeżeli podamy "" (wartość domyślna) funkcja zwróci uchwyt do obrazu.

$hWnd - uchwyt do okna, jeżeli podamy -1 to zrzut dotyczy całego ekranu, podanie "" oznacza okno aktywne.

$left i $top - współrzędne lewego górnego narożnika zrzucanego obrazu, dla ekranu są to współrzędne absolutne, dla okna współrzędne względne okna, podanie -1 (wartość domyślna oznacza tyle co 0. Jeżeli dla $left podamy wartość -2, będzie to oznaczało zrzut przestrzeni roboczej okna, dalsze parametry nie mają wtedy znaczenia.

$w i $h - długość i szerokość zrzucanego obszaru, podanie -1 oznacza obszar do końca zrzucanego obiektu (ekranu lub okna)

$Cursor - oznacza czy ma być zrzucony także kursor, domyślna wartość True oznacza, że kursor będzie zrzucony, dla zrzutu przestrzeni roboczej okna kursor nigdy nie jest zrzucany.

$frame - szerokość ramki przy zrzucie okna, domyślna wartość 4 jest odpowiednia przy W7, dla XP ramka wokół okna jest węższa więc lepiej użyć wartości 0.

Przykład użycia i implementacja funkcji:

 
#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>

#region tworzenie testowego obrazka
$hGUI = GUICreate("GDI+", 400, 300)
GUISetState()

_GDIPlus_Startup()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)

;rysowanie elipsy domyślnym pędzlem
_GDIPlus_GraphicsfillEllipse($hGraphic, 160, 100, 150, 100)

$hBrush = _GDIPlus_BrushCreateSolid(0xB0FF0000) ;tworzenie pędzla
_GDIPlus_GraphicsFillEllipse($hGraphic, 210, 30, 120, 250, $hBrush)
Sleep(300) ;chwila na zakończenie tworzenia obrazka

;zwolnienie zasobów
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_Shutdown()
#endregion tworzenie testowego obrazka

_ScreenCapturePlus("cały ekran.jpg", -1)
_ScreenCapturePlus("frament ekranu.jpg", -1, 500, 200, 400, -1)
_ScreenCapturePlus("całe okno.jpg", $hGUI)
_ScreenCapturePlus("frament okna.jpg", $hGUI, 50, 50, -1, -1)
_ScreenCapturePlus("obszar roboczy okna.jpg", "", -2)

MsgBox(0,"_ScreenCapturePlus", "Zrzut wykonany", 2)




;implementacja
Func _ScreenCapturePlus($file="", $hWnd=-1, $left=-1, $top=-1, $w=-1, $h=-1, $Cursor=True, $frame=4)
   Local $hDC, $memBmp, $memDC, $hImage, $ar, $aCursor, $hIcon, $aIcon
   Local Const $SRCCOPY = 0x00CC0020

   If $hWnd = "" Then $hWnd = WinGetHandle("[ACTIVE]")
   If $left = -1 Then $left = 0
   If $top = -1 Then $top =0

   Select
      Case $hWnd=-1 And $left >= -1 ;dane do zrzutu całego ekranu
         If $w = -1 Then $w = @DesktopWidth - $left
         If $h = -1 Then $h = @DesktopHeight - $top
         $hWnd = WinGetHandle(Default)
      Case $hWnd <> -1 And $left >= -1 ;dane do zrzut okna
         $ar = WinGetPos($hWnd)
         If $w = -1 Then $w = $ar[2]+2*$frame-$left
         If $h = -1 Then $h = $ar[3]+2*$frame-$top
         $left = $left + $ar[0] - $frame
         $top = $top + $ar[1] - $frame
         $hWnd = WinGetHandle(Default)
      Case $left < -1 ;dane do zrzutu przestrzeni roboczej okne
         $ar = WinGetClientSize($hWnd)
         $w = $ar[0]
         $h = $ar[1]
         $left = 0
         $top = 0
         $cursor = False
   EndSelect
	 
   ;zrzut ekranu lub jego fragmentu
   $hDC = _WinAPI_GetDC($hWnd)
   $memDC = _WinAPI_CreateCompatibleDC($hDC)
   $memBmp = _WinAPI_CreateCompatibleBitmap($hDC, $w, $h)
   _WinAPI_SelectObject($memDC, $memBmp)
   _WinAPI_BitBlt($memDC, 0, 0, $w, $h, $hDC, $left, $top, $SRCCOPY)
   
   If $Cursor Then ;zrzut kursora
      $aCursor = _WinAPI_GetCursorInfo()
      If $aCursor[1] Then
         $aIcon = _WinAPI_GetIconInfo($aCursor[2])
		 ;domalowanie kursora
         _WinAPI_DrawIcon($memDC, $aCursor[3]-$aIcon[2]-$left, $aCursor[4]-$aIcon[3]-$top, $aCursor[2])
      EndIf
   EndIf
  
   _GDIPlus_Startup()
   $hImage = _GDIPlus_BitmapCreateFromHBITMAP($memBmp)
   If $file = "" Then Return $hImage
   _GDIPlus_ImageSaveToFile($hImage, $file)

   ;zwolnienie zasobów
   _GDIPlus_ImageDispose($hImage)
   _WinAPI_ReleaseDC($hWnd, $hDC)
   _WinAPI_DeleteDC($memDC)
   _WinAPI_DeleteObject($memBmp)
   _GDIPlus_Shutdown()
EndFunc


Można też użyć poniższej funkcji wykorzystującej klawisz PrintScreen i schowek systemowy:

_ScreenCapturePS

edytuj
#include <GDIPlus.au3>
_ScreenCapturePS($file="", $hWnd=-1, $left=-1, $top=-1, $w=-1, $h=-1, $Cursor=True, $frame=0)

Funkcja działa dokładnie tak jak funkcja _ScreenCapturePlus (opis działania i parametrów jest identyczny).

Przykład użycia i implementacja funkcji:

#include <Constants.au3>
#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>

#region tworzenie testowego obrazka
$hGUI = GUICreate("GDI+", 400, 300)
GUISetState()

_GDIPlus_Startup()
$hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)

;rysowanie elipsy domyślnym pędzlem
_GDIPlus_GraphicsfillEllipse($hGraphic, 160, 100, 150, 100)

$hBrush = _GDIPlus_BrushCreateSolid(0xB0FF0000) ;tworzenie pędzla
_GDIPlus_GraphicsFillEllipse($hGraphic, 210, 30, 120, 250, $hBrush)
Sleep(200) ;chwila na zakończenie tworzenia obrazka

;zwolnienie zasobów
_GDIPlus_BrushDispose($hBrush)
_GDIPlus_GraphicsDispose($hGraphic)
_GDIPlus_Shutdown()
#endregion tworzenie testowego obrazka

_ScreenCapturePS("cały ekran.jpg", -1)
_ScreenCapturePS("frament ekranu.jpg", -1, 500, 200, 400, -1)
_ScreenCapturePS("całe okno.jpg", $hGUI)
_ScreenCapturePS("frament okna.jpg", $hGUI, 50, 50, -1, -1)
_ScreenCapturePS("obszar roboczy okna.jpg", "", -2)

MsgBox(0,"_ScreenCapturePS", "Zrzut wykonany", 2)


;implementacja
Func _ScreenCapturePS($file="", $hWnd=-1, $left=-1, $top=-1, $w=-1, $h=-1, $cursor=True, $frame=4)
   Local $hBitmap, $aCursor, $hDC, $mDC, $aIcon, $hBmp, $hImage, $ar, $arc

   If $hWnd = "" Then $hWnd = WinGetHandle("[ACTIVE]")
   If $left = -1 Then $left = 0
   If $top = -1 Then $top =0

   Select
      Case $hWnd=-1 And $left >= -1 ;dane do zrzutu całego ekranu
         If $w = -1 Then $w = @DesktopWidth - $left
         If $h = -1 Then $h = @DesktopHeight - $top
         $hWnd = WinGetHandle(Default)
      Case $hWnd <> -1 And $left >= -1 ;dane do zrzut okna
         $ar = WinGetPos($hWnd)
         If $w = -1 Then $w = $ar[2]+2*$frame-$left
         If $h = -1 Then $h = $ar[3]+2*$frame-$top
         $left = $left + $ar[0] - $frame
         $top = $top + $ar[1] - $frame
         $hWnd = WinGetHandle(Default)
      Case $left < -1 ;dane do zrzutu przestrzeni roboczej okne
         $ar = WinGetPos($hWnd)
         $arc = WinGetClientSize($hWnd)
         $left = $ar[0] + ($ar[2]-$arc[0])/2
         $top = $ar[1] + $ar[3] - $arc[1] - ($ar[2]-$arc[0])/2
         $w = $arc[0]
         $h = $arc[1]
         $cursor = False
   EndSelect

   Send("{PRINTSCREEN}") ;zrzut ekranu do schowka klawiszem PrintScreen
   ;pobranie bitmapy ze schowka
   DllCall("user32.dll", "bool", "OpenClipboard", "hwnd", 0)
   $ar = DllCall("user32.dll", "handle", "GetClipboardData", "uint", 2)
   $hBitmap = $ar[0]
   DllCall("user32.dll", "bool", "CloseClipboard")

   If $cursor Then ;zrzut kursora
      $aCursor = _WinAPI_GetCursorInfo()
      If $aCursor[1] Then ;jeżeli kursor jest widoczny
         $aIcon = _WinAPI_GetIconInfo($aCursor[2])
         $hDC = _WinAPI_GetWindowDC($hWnd)
         $mDC =  _WinAPI_CreateCompatibleDC($hDC)
         _WinAPI_SelectObject($mDC, $hBitmap)
         ;wrysowanie kursora w bitmapę
         _WinAPI_DrawIcon($mDC, $aCursor[3]-$aIcon[2], $aCursor[4]-$aIcon[3], $aCursor[2])
      EndIf
   EndIf

   _GDIPlus_Startup()
   ;tworzenie obiektu bitmap z bitmapy
   $hBmp =_GDIPlus_BitmapCreateFromHBITMAP($hBitmap)

   ;wycięcie obrazu z obiektu bitmap
   $hImage =_GDIPlus_BitmapCloneArea($hBmp, $left, $top, $w, $h)

   If $file="" Then Return $hImage 
   _GDIPlus_ImageSaveToFile($hImage, $file) ;zapis obrazu na dysku

   ;zwolnienie zasobów
   _GDIPlus_ImageDispose($hImage)
   _WinAPI_ReleaseDC($hWnd, $hDC)
   _WinAPI_DeleteDC($mDC)
   _WinAPI_DeleteObject($hBitmap)
   _GDIPlus_Shutdown()
EndFunc