Jump to content
Sign in to follow this  
andd

Capturing an Image

Recommended Posts

andd

Hi,

I was wondering if there is any way to do screenshots with AutoIt. At first I coded a *.dll in Delphi which saves the entire screen, or a window given by its handle, to an image in jpeg-format.

Then I noticed, that there already exists an *.dll in this forum, which does nearly the same. So I decided to do it only with AutoIt by using standard DllCalls.

Windows handles the entire screen like a common window, so you can get its handle by using the "GetDesktopWindow" dllcall of the user32.dll. For the picture information you need to get the device context by calling "GetWindowDC". Now you create a compatible device context (in memory) where you can store the picture information of the screen. Before copying the data via bit block transfer, you have to create a compatible bitmap and select it to the compatible device context to store the exact picture information (otherwise it would be monochrom).

Now I'm so far, that I can capture an image, for example the whole screen or just a window. I got help from MSDN and made it with AutoIt.

; Screenshot via Dll

$hwnd = DllCall("user32.dll","hwnd","GetDesktopWindow") 
; get handle to entire screen 

$DC = DllCall("user32.dll","ptr","GetWindowDC","hwnd",$hwnd[0]) 
; get device context for picture information

$lpRect = DllStructCreate("int;int;int;int") 
; create DllStruct for GetWindowRect call

DllCall("user32.dll","int","GetWindowRect","hwnd",$hwnd[0],"ptr",DllStructGetPtr($lpRect)) 
; get coordinates from upper-left and lower-right corner

$cDC = DllCall("gdi32.dll","ptr","CreateCompatibleDC","ptr",$DC[0]) 
; create compatible DC

$hbmp = DllCall("gdi32.dll","hwnd","CreateCompatibleBitmap","ptr",$DC[0],"int",DllStructGetData($lpRect,3),"int",DllStructGetData($lpRect,3))
; create compatible bitmap

DllCall("gdi32.dll","hwnd","SelectObject","ptr",$cDC[0],"hwnd",$hbmp[0])
; select bitmap to device context

DllCall("gdi32.dll","int","BitBlt","ptr",$cDC[0],"int",0,"int",0,"int",DllStructGetData($lpRect,3),"int",DllStructGetData($lpRect,3),"ptr",$DC[0],"int",0,"int",0,"int",0x00CC0020)
; copy picture information from the screen to device context in memory

Sleep(5000)
; break for doing anything on screen

DllCall("gdi32.dll","int","BitBlt","ptr",$DC[0],"int",0,"int",0,"int",DllStructGetData($lpRect,3),"int",DllStructGetData($lpRect,3),"ptr",$cDC[0],"int",0,"int",0,"int",0x00CC0020)
; restore previous saved screen

DllCall("user32.dll","int","ReleaseDC","hwnd",$hwnd[0],"ptr",$cDC[0]); release device context for use by other apps

DllCall("user32.dll","int","ReleaseDC","hwnd",$hwnd[0],"ptr",$DC[0]); release device context for use by other apps

The next step would be to store the image to a file instead of memory: MSDN ...but that should take a while :whistle:

Share this post


Link to post
Share on other sites
kjactive

Well I found something semilare - maybe you can use this in some manner...

Capture full screen as jpg...

parameter: library,Function,filename,jpeg quality. 
DllCall("captdll.dll", "int", "CaptureScreen", "str", "?.jpg", "int", 85)

Capture region as bitmap...

parameter: Library,Function,filename, left, top, width, height, jpeg quality.
(Set quality to any negative number to capture into BMP)
DllCall("captdll.dll", "int", "CaptureRegion", "str", "?.bmp", "int", 100, "int", 100, "int", 300, "int", 200, "int", -1)

captdll library has to be in the system...

I don't remember where it came from but work nicely...

kjactive :whistle:

Edited by kjactive

Share this post


Link to post
Share on other sites
Lazycat

Hi,

I was wondering if there is any way to do screenshots with AutoIt. At first I coded a *.dll in Delphi which saves the entire screen, or a window given by its handle, to an image in jpeg-format.

Then I noticed, that there already exists an *.dll in this forum, which does nearly the same. So I decided to do it only with AutoIt by using standard DllCalls.

You can get this dll with source in my fileman:

http://www.autoitscript.com/fileman/users/Lazycat/

This will be very usefull, if you done it in native Au3 code, at least bmp part.

Share this post


Link to post
Share on other sites
andd

Found an interesting dll-call (StrechtBlt) and did something like that:

#include <GUIConstants.au3>

GUICreate("Lupe",202,202,@DesktopWidth-204,0,$WS_BORDER)
GUISetState (@SW_SHOW)   

$hwnd = DllCall("user32.dll","hwnd","GetDesktopWindow")
$DC = DllCall("user32.dll","ptr","GetWindowDC","hwnd",$hwnd[0])

$lpRect = DllStructCreate("int;int;int;int")
DllCall("user32.dll","int","GetWindowRect","hwnd",$hwnd[0],"ptr",DllStructGetPtr($lpRect))

$cDC = DllCall("gdi32.dll","ptr","CreateCompatibleDC","ptr",$DC[0])
$hbmp = DllCall("gdi32.dll","hwnd","CreateCompatibleBitmap","ptr",$DC[0],"int",DllStructGetData($lpRect,3),"int",DllStructGetData($lpRect,3))
DllCall("gdi32.dll","hwnd","SelectObject","ptr",$cDC[0],"hwnd",$hbmp[0])

While 1
    $msg = GUIGetMsg()
    Lupe()
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
Wend

DllCall("user32.dll","int","ReleaseDC","hwnd",$hwnd[0],"ptr",$cDC[0])
DllCall("user32.dll","int","ReleaseDC","hwnd",$hwnd[0],"ptr",$DC[0])

Exit

Func Lupe()
$pos = MouseGetPos()
If $pos[0] < 50 Then $pos[0] = 50
If $pos[1] < 50 Then $pos[1] = 50
If $pos[0] >= (@DesktopWidth - 50) Then $pos[0] = @DesktopWidth - 50
If $pos[1] >= (@DesktopHeight - 50) Then $pos[1] = @DesktopHeight - 50
    
DllCall("gdi32.dll","int","BitBlt","ptr",$cDC[0],"int",0,"int",0,"int",100,"int",100,"ptr",$DC[0],"int",$pos[0]-50,"int",$pos[1]-50,"int",0x00CC0020)

$GUIhwnd = WinGetHandle("Lupe")
$GUIDC = DllCall("user32.dll","ptr","GetWindowDC","hwnd",$GUIhwnd)
DllCall("gdi32.dll","int","StretchBlt","ptr",$GUIDC[0],"int",2,"int",2,"int",200,"int",200,"ptr",$cDC[0],"int",0,"int",0,"int",100,"int",100,"int",0x00CC0020)
EndFunc

Edit:

added screenshot as attachment

Lupe.zip

Edited by andd

Share this post


Link to post
Share on other sites
Mosquitos

I use the script and dll from lazycat and change the script a little bit...

; Capture full screen
; Fist parameter - filename, last - jpeg quality. 
$sFileName = @MON & "." & @MDAY & "." & @YEAR & " - " & @HOUR & "." & @MIN & "." & @SEC
DllCall("captdll.dll", "int", "CaptureScreen", "str", "" & $sFileName & ".jpg", "int", 85)

I use only the jpg.

Edited by Mosquitos

Sapiente vince, rex, noli vincere ferro!

Share this post


Link to post
Share on other sites
andd

Thx for your replies.

I wrote also a *.dll (because I couldn't find lazycat's one at first). I think I'll use one of the both in the future.

But if someone finds a solution in native AuoIt, that would be interesting for me :whistle:

Thx & Cu

Share this post


Link to post
Share on other sites
busysignal

Very nice. I can dig all the information.

Cheers.. ;)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×