AutoIt/Zrzut ekranu
Zrzut ekranu
edytujZa 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
edytujPonieważ 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