Sign in to follow this  
Followers 0
ITSky8

How to scale Screen Captured Image?

7 posts in this topic

Hello!

I know that AutoIT can capture the screen, and save it to as JPG, or PNG etc, but how to resize the captured screen, e.g. The captured size is 800x600 pixels, how to scale it to 400x300 pixels etc, does it possible to do that?

Share this post


Link to post
Share on other sites



Hi, you can use _GDIPlus_GraphicsDrawImageRect($hGraphics, $hImage, $iX, $iY, $iW, $iH ).

The function can be found in AutoIt Beta 3.2.11.0 onwards.

You can find it in the help file under User Defined Functions -> GDIPlus Management.

Cheers

Share this post


Link to post
Share on other sites

Hello!

Why this doesn't work? My image size is 800x600, it can capture and create an image as 800x600, but the resize is doesn't work, what's wrong? And why? Please help? Thanks!

Func CapScreen()

Local $cap1,$hGUI1, $hGUI2, $hImage, $hGraphic1, $hGraphic2

$cap1 = _ScreenCapture_Capture("",0, 0, 800, 600)

_ScreenCapture_SaveImage ("c:\temp\test.png",$cap1)

; Initialize GDI+ library and load image

_GDIPlus_Startup ()

$hImage = _GDIPlus_ImageLoadFromFile ("c:\temp\test.png")

; Create a GUI for the original image

$hGUI1 = GUICreate("Original", 0, 0, 800, 600)

GUISetState()

; Create a GUI for the szied image

$hGUI2 = GUICreate("Sized", 0, 0, 600, 300)

GUISetState()

; Draw original image

$hGraphic1 = _GDIPlus_GraphicsCreateFromHWND ($hGUI1)

_GDIPlus_GraphicsDrawImage ($hGraphic1, $hImage, 0, 0)

; Resize to 600x300

$hGraphic2 = _GDIPlus_GraphicsCreateFromHWND ($hGUI2)

_GDIPlus_GraphicsDrawImageRectRect ($hGraphic2, $hImage, 0, 0, 800, 600, 0, 0, 600, 300)

; Release resources

;_GDIPlus_GraphicsDispose ($hGraphic1)

_GDIPlus_GraphicsDispose ($hGraphic2)

_GDIPlus_ImageDispose ($hImage)

_GDIPlus_Shutdown ()

EndFunc

Share this post


Link to post
Share on other sites

Hi, here's a crude example using AutoIt Public Release 3.2.10.0

#include <GUIConstants.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <WinAPI.au3>

Global $apw = 400, $aph = 300, $TempFile = @ScriptDir & "\GDIPlus_temp.jpg"

$Gui = GUICreate("Capture To Size", $apw, $aph)
_CapToSize($apw, $aph, $TempFile)
GUICtrlCreatePic($TempFile, -1, -1, $apw, $aph)
GUICtrlSetState(-1, $GUI_DISABLE)
GUISetState()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            Exit
        Case Else
            ;;;;
    EndSwitch
WEnd    


Func _CapToSize($sW, $sH, $sPath)
    Local $hBitmap1, $hImage1, $hGraphic, $hBitmap2, $hImage2, $sCLSID
    _GDIPlus_Startup()

    $hBitmap1 = _CreateBitmap($sW, $sH)
    $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap1)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage1)

    $hBitmap2 = _ScreenCapture_Capture("")
    $hImage2 = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap2)

    _GDIPLus_GraphicsDrawImageRect($hGraphic, $hImage2, 0, 0, 400, 300)

    $sCLSID = _GDIPlus_EncodersGetCLSID("JPG")
    _GDIPlus_ImageSaveToFileEx($hImage1, $sPath, $sCLSID)

    
    _GDIPlus_ImageDispose ($hImage1)
    _GDIPlus_ImageDispose ($hImage2)
    _GDIPlus_GraphicsDispose($hGraphic)
    
    _WinAPI_DeleteObject ($hBitmap1)
    _WinAPI_DeleteObject ($hBitmap2)

    _GDIPlus_ShutDown ()
EndFunc

Func _GDIPLus_GraphicsDrawImageRect($hGraphics, $hImage, $iX, $iY, $iW, $iH)
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipDrawImageRectI", "hwnd", $hGraphics, "hwnd", $hImage, _
                                                        "int", $iX, "int", $iY, "int", $iW, "int", $iH)
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc   ;==>_GDIPlus_GraphicsDrawImageRect

Func _CreateBitmap($iW, $iH)
    Local $hWnd, $hDDC, $hCDC, $hBMP
    $hWnd = _WinAPI_GetDesktopWindow()
    $hDDC = _WinAPI_GetDC($hWnd)
    $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
    $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iW, $iH)
    _WinAPI_ReleaseDC($hWnd, $hDDC)
    _WinAPI_DeleteDC($hCDC)
    Return $hBMP
EndFunc   ;==>_CreateBitmap
Note if your using AutoIt Beta v 3.2.11.0 then you'll need to comment out the _GDIPLus_GraphicsDrawImageRect() function out of the above script.

Cheers

Share this post


Link to post
Share on other sites

Hello!

I have tested your suggestion, it's work, but how to capture the defined region? As I found that you are using the $hWnd = _WinAPI_GetDesktopWindow(), it will capture whole Desktop, but not the defined region? Thanks!

Hi, here's a crude example using AutoIt Public Release 3.2.10.0

#include <GUIConstants.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <WinAPI.au3>

Global $apw = 400, $aph = 300, $TempFile = @ScriptDir & "\GDIPlus_temp.jpg"

$Gui = GUICreate("Capture To Size", $apw, $aph)
_CapToSize($apw, $aph, $TempFile)
GUICtrlCreatePic($TempFile, -1, -1, $apw, $aph)
GUICtrlSetState(-1, $GUI_DISABLE)
GUISetState()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            Exit
        Case Else
            ;;;;
    EndSwitch
WEnd    


Func _CapToSize($sW, $sH, $sPath)
    Local $hBitmap1, $hImage1, $hGraphic, $hBitmap2, $hImage2, $sCLSID
    _GDIPlus_Startup()

    $hBitmap1 = _CreateBitmap($sW, $sH)
    $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap1)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage1)

    $hBitmap2 = _ScreenCapture_Capture("")
    $hImage2 = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap2)

    _GDIPLus_GraphicsDrawImageRect($hGraphic, $hImage2, 0, 0, 400, 300)

    $sCLSID = _GDIPlus_EncodersGetCLSID("JPG")
    _GDIPlus_ImageSaveToFileEx($hImage1, $sPath, $sCLSID)

    
    _GDIPlus_ImageDispose ($hImage1)
    _GDIPlus_ImageDispose ($hImage2)
    _GDIPlus_GraphicsDispose($hGraphic)
    
    _WinAPI_DeleteObject ($hBitmap1)
    _WinAPI_DeleteObject ($hBitmap2)

    _GDIPlus_ShutDown ()
EndFunc

Func _GDIPLus_GraphicsDrawImageRect($hGraphics, $hImage, $iX, $iY, $iW, $iH)
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipDrawImageRectI", "hwnd", $hGraphics, "hwnd", $hImage, _
                                                        "int", $iX, "int", $iY, "int", $iW, "int", $iH)
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc   ;==>_GDIPlus_GraphicsDrawImageRect

Func _CreateBitmap($iW, $iH)
    Local $hWnd, $hDDC, $hCDC, $hBMP
    $hWnd = _WinAPI_GetDesktopWindow()
    $hDDC = _WinAPI_GetDC($hWnd)
    $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
    $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iW, $iH)
    _WinAPI_ReleaseDC($hWnd, $hDDC)
    _WinAPI_DeleteDC($hCDC)
    Return $hBMP
EndFunc   ;==>_CreateBitmap
Note if your using AutoIt Beta v 3.2.11.0 then you'll need to comment out the _GDIPLus_GraphicsDrawImageRect() function out of the above script.

Cheers

Share this post


Link to post
Share on other sites

Hi, sorry for the slow response, but I work away from home 4 days a week, just got back :)

I think you missed what the _CreateBitmap($iW, $iH) function actually does, basically it's just a canvas to paint the screen capture onto.

To be able to capture a region and scale the capture you can just add some more parameters to the function like so..

#include <GUIConstants.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <WinAPI.au3>

Global $regX = @DesktopWidth / 2, $regY = @DesktopHeight / 2, $regW = @DesktopWidth / 2, $regH = @DesktopHeight / 2
Global $apw = 200, $aph = 150, $TempFile = @ScriptDir & "\GDIPlus_temp.jpg"

$Gui = GUICreate("Capture To Size", $apw, $aph)
_CapToSize($regX, $regY, $regW, $regH, $apw, $aph, $TempFile)
GUICtrlCreatePic($TempFile, -1, -1, $apw, $aph)
GUICtrlSetState(-1, $GUI_DISABLE)
GUISetState()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            Exit
        Case Else
            ;;;;
    EndSwitch
WEnd    

;$rX is the Left position of the region to capture
;$rY is the Top position of the region to capture
;$rW is the Width of the region to capture
;$rH is the Height of the region to capture
;$sW is the Width to scale the captured region to.
;$sH is the Height to scale the captured region to.
;$sPath is the file path/name to save the scaled region cature to.

Func _CapToSize($rX, $rY, $rW, $rH, $sW, $sH, $sPath)
    Local $hBitmap1, $hImage1, $hGraphic, $hBitmap2, $hImage2, $sCLSID
    _GDIPlus_Startup()

    $hBitmap1 = _CreateBitmap($sW, $sH)
    $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap1)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage1)

    $hBitmap2 = _ScreenCapture_Capture("", $rX, $rY, $rX + $rW, $rY + $rH)
    $hImage2 = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap2)

    _GDIPLus_GraphicsDrawImageRect($hGraphic, $hImage2, 0, 0, $apw, $aph)

    $sCLSID = _GDIPlus_EncodersGetCLSID("JPG")
    _GDIPlus_ImageSaveToFileEx($hImage1, $sPath, $sCLSID)

    
    _GDIPlus_ImageDispose ($hImage1)
    _GDIPlus_ImageDispose ($hImage2)
    _GDIPlus_GraphicsDispose($hGraphic)
    
    _WinAPI_DeleteObject ($hBitmap1)
    _WinAPI_DeleteObject ($hBitmap2)

    _GDIPlus_ShutDown ()
EndFunc

Func _GDIPLus_GraphicsDrawImageRect($hGraphics, $hImage, $iX, $iY, $iW, $iH)
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipDrawImageRectI", "hwnd", $hGraphics, "hwnd", $hImage, _
                                                        "int", $iX, "int", $iY, "int", $iW, "int", $iH)
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc   ;==>_GDIPlus_GraphicsDrawImageRect

Func _CreateBitmap($iW, $iH)
    Local $hWnd, $hDDC, $hCDC, $hBMP
    $hWnd = _WinAPI_GetDesktopWindow()
    $hDDC = _WinAPI_GetDC($hWnd)
    $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
    $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iW, $iH)
    _WinAPI_ReleaseDC($hWnd, $hDDC)
    _WinAPI_DeleteDC($hCDC)
    Return $hBMP
EndFunc   ;==>_CreateBitmap

Cheers

Share this post


Link to post
Share on other sites

Thanks for your kindly response! You are really offered a great help! But I still have a lot of things want to learn from you, if you are available, then you may offer your help, thanks!

Q1) How to detect the popup dialog? As I found that the AutoIT will pop up error dialog, so I want to write another AutoIT program (Monitor.exe) to monitor the Screen_Cap.exe, once detected the error dialog, thn Monitor.exe will kill the Screen_cap.exe, and restart the Screen_cap.exe again. Now I am using the PixelGetColor method, but it's not so accurate, I detect the pop up dialog region's color change, if match, then Kill the Screen_cap.exe and restart again, but I found that sometimes it doesn't work?

Q2) How to capture the Active Window, e.g. Capture the opened Word only?

Q3) How to send out notification email by AutoIT to notify the System Administrator, once the Screen_cap.exe pop up error dialog?

Hi, sorry for the slow response, but I work away from home 4 days a week, just got back :)

I think you missed what the _CreateBitmap($iW, $iH) function actually does, basically it's just a canvas to paint the screen capture onto.

To be able to capture a region and scale the capture you can just add some more parameters to the function like so..

#include <GUIConstants.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <WinAPI.au3>

Global $regX = @DesktopWidth / 2, $regY = @DesktopHeight / 2, $regW = @DesktopWidth / 2, $regH = @DesktopHeight / 2
Global $apw = 200, $aph = 150, $TempFile = @ScriptDir & "\GDIPlus_temp.jpg"

$Gui = GUICreate("Capture To Size", $apw, $aph)
_CapToSize($regX, $regY, $regW, $regH, $apw, $aph, $TempFile)
GUICtrlCreatePic($TempFile, -1, -1, $apw, $aph)
GUICtrlSetState(-1, $GUI_DISABLE)
GUISetState()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            Exit
        Case Else
            ;;;;
    EndSwitch
WEnd    

;$rX is the Left position of the region to capture
;$rY is the Top position of the region to capture
;$rW is the Width of the region to capture
;$rH is the Height of the region to capture
;$sW is the Width to scale the captured region to.
;$sH is the Height to scale the captured region to.
;$sPath is the file path/name to save the scaled region cature to.

Func _CapToSize($rX, $rY, $rW, $rH, $sW, $sH, $sPath)
    Local $hBitmap1, $hImage1, $hGraphic, $hBitmap2, $hImage2, $sCLSID
    _GDIPlus_Startup()

    $hBitmap1 = _CreateBitmap($sW, $sH)
    $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap1)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage1)

    $hBitmap2 = _ScreenCapture_Capture("", $rX, $rY, $rX + $rW, $rY + $rH)
    $hImage2 = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap2)

    _GDIPLus_GraphicsDrawImageRect($hGraphic, $hImage2, 0, 0, $apw, $aph)

    $sCLSID = _GDIPlus_EncodersGetCLSID("JPG")
    _GDIPlus_ImageSaveToFileEx($hImage1, $sPath, $sCLSID)

    
    _GDIPlus_ImageDispose ($hImage1)
    _GDIPlus_ImageDispose ($hImage2)
    _GDIPlus_GraphicsDispose($hGraphic)
    
    _WinAPI_DeleteObject ($hBitmap1)
    _WinAPI_DeleteObject ($hBitmap2)

    _GDIPlus_ShutDown ()
EndFunc

Func _GDIPLus_GraphicsDrawImageRect($hGraphics, $hImage, $iX, $iY, $iW, $iH)
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipDrawImageRectI", "hwnd", $hGraphics, "hwnd", $hImage, _
                                                        "int", $iX, "int", $iY, "int", $iW, "int", $iH)
    If @error Then Return SetError(@error, @extended, 0)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc   ;==>_GDIPlus_GraphicsDrawImageRect

Func _CreateBitmap($iW, $iH)
    Local $hWnd, $hDDC, $hCDC, $hBMP
    $hWnd = _WinAPI_GetDesktopWindow()
    $hDDC = _WinAPI_GetDC($hWnd)
    $hCDC = _WinAPI_CreateCompatibleDC($hDDC)
    $hBMP = _WinAPI_CreateCompatibleBitmap($hDDC, $iW, $iH)
    _WinAPI_ReleaseDC($hWnd, $hDDC)
    _WinAPI_DeleteDC($hCDC)
    Return $hBMP
EndFunc   ;==>_CreateBitmap

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  
Followers 0