Sign in to follow this  
Followers 0
Wombat

Drawing on a ScreenCapture

7 posts in this topic

#1 ·  Posted (edited)

Alright so I have this script that I pulled from the depths of the forum, Melba23 was the author of the original code. I changed it to meet my requirements (thank you Melba23)

 

I now wish to add the functionality of being able to draw on the image, as well as being able to save the edited file. Where do I start, I've scavenged, dug around and can't find any examples that help.

 

I'm looking for the simplest way to do this, I know I can use GDI, but I would like to avoid that if possible.

 

Anywho, here is the code:

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ScreenCapture.au3>
#include <Misc.au3>
#include <StaticConstants.au3>
#include <File.au3>
#include <Array.au3>

Opt("GUIOnEventMode", 1)

Global Const $SYSTEMROOT = EnvGet('systemdrive')
Global $iX1, $iY1, $iX2, $iY2, $aPos, $sMsg, $sBMP_Path, $dc
Global $editValue = False



; Create GUI
$hMain_GUI = GUICreate("Select Rectangle", 400, 50)
GUISetOnEvent($GUI_EVENT_CLOSE, "mGUI_Close", "Select Rectangle")

$hRect_Button = GUICtrlCreateButton("Capture", 10, 10, 80, 30)
GUICtrlSetOnEvent(-1, "_Capture")
$hCancel_Button = GUICtrlCreateButton("Cancel", 310, 10, 80, 30)
GUICtrlSetOnEvent(-1, "mGUI_Close")
$hEdit_Button = GUICtrlCreateButton("Edit", 110, 10, 80, 30)
GUICtrlSetState($hEdit_Button, $GUI_DISABLE)
GUICtrlSetOnEvent(-1, "_Edit")
$hSave_Button = GUICtrlCreateButton("Save", 210, 10, 80, 30)
GUICtrlSetOnEvent(-1, "_Save")
GUICtrlSetState($hSave_Button, $GUI_DISABLE)

GUISetState()

While 1

    Sleep(10)
WEnd


Func Mark_Rect()

    Local $aMouse_Pos, $hMask, $hMaster_Mask, $iTemp
    Local $UserDLL = DllOpen("user32.dll")

    Global $hRectangle_GUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
    _GUICreateInvRect($hRectangle_GUI, 0, 0, 1, 1)
    GUISetBkColor(0)
    WinSetTrans($hRectangle_GUI, "", 75)
    GUISetState(@SW_SHOW, $hRectangle_GUI)
    GUISetCursor(3, 1, $hRectangle_GUI)

    ; Wait until mouse button pressed
    While Not _IsPressed("01", $UserDLL)
        Sleep(10)
    WEnd

    ; Get first mouse position
    $aMouse_Pos = MouseGetPos()
    $iX1 = $aMouse_Pos[0]
    $iY1 = $aMouse_Pos[1]

    ; Draw rectangle while mouse button pressed
    While _IsPressed("01", $UserDLL)

        $aMouse_Pos = MouseGetPos()

        ; Set in correct order if required
        If $aMouse_Pos[0] < $iX1 Then
            $iX_Pos = $aMouse_Pos[0]
            $iWidth = $iX1 - $aMouse_Pos[0]
        Else
            $iX_Pos = $iX1
            $iWidth = $aMouse_Pos[0] - $iX1
        EndIf
        If $aMouse_Pos[1] < $iY1 Then
            $iY_Pos = $aMouse_Pos[1]
            $iHeight = $iY1 - $aMouse_Pos[1]
        Else
            $iY_Pos = $iY1
            $iHeight = $aMouse_Pos[1] - $iY1
        EndIf

        _GUICreateInvRect($hRectangle_GUI, $iX_Pos, $iY_Pos, $iWidth, $iHeight)

        Sleep(10)

    WEnd

    ; Get second mouse position
    $iX2 = $aMouse_Pos[0]
    $iY2 = $aMouse_Pos[1]

    ; Set in correct order if required
    If $iX2 < $iX1 Then
        $iTemp = $iX1
        $iX1 = $iX2
        $iX2 = $iTemp
    EndIf
    If $iY2 < $iY1 Then
        $iTemp = $iY1
        $iY1 = $iY2
        $iY2 = $iTemp
    EndIf

    GUIDelete($hRectangle_GUI)
    DllClose($UserDLL)

EndFunc   ;==>Mark_Rect

Func _GUICreateInvRect($hWnd, $iX, $iY, $iW, $iH)

    $hMask_1 = _WinAPI_CreateRectRgn(0, 0, @DesktopWidth, $iY)
    $hMask_2 = _WinAPI_CreateRectRgn(0, 0, $iX, @DesktopHeight)
    $hMask_3 = _WinAPI_CreateRectRgn($iX + $iW, 0, @DesktopWidth, @DesktopHeight)
    $hMask_4 = _WinAPI_CreateRectRgn(0, $iY + $iH, @DesktopWidth, @DesktopHeight)

    _WinAPI_CombineRgn($hMask_1, $hMask_1, $hMask_2, 2)
    _WinAPI_CombineRgn($hMask_1, $hMask_1, $hMask_3, 2)
    _WinAPI_CombineRgn($hMask_1, $hMask_1, $hMask_4, 2)

    _WinAPI_DeleteObject($hMask_2)
    _WinAPI_DeleteObject($hMask_3)
    _WinAPI_DeleteObject($hMask_4)

    _WinAPI_SetWindowRgn($hWnd, $hMask_1, 1)

EndFunc   ;==>_GUICreateInvRect

; -------------

Func _Capture()
    If WinExists("Captured Image", "") = 1 Then GUIDelete("Captured Image")
    FileDelete(@ScriptDir & "\temp.jpg")
    GUISetState(@SW_HIDE, $hMain_GUI)
    Mark_Rect()
    ; Capture selected area
    $sBMP_Path = @ScriptDir & "\temp.jpg"
    _ScreenCapture_Capture($sBMP_Path, $iX1, $iY1, $iX2, $iY2, False)
    GUISetState(@SW_SHOW, $hMain_GUI)
    WinMove("Select Rectangle", "", Default + 75, Default + 100)
    GUICtrlSetState($hSave_Button, $GUI_ENABLE)
    GUICtrlSetState($hEdit_Button, $GUI_ENABLE)
    ; Display image
    $hBitmap_GUI = GUICreate("Captured Image", $iX2 - $iX1 + 50, $iY2 - $iY1 + 50, Default, Default)
    GUISetBkColor(0x525252, "Captured Image")
    GUISetOnEvent($GUI_EVENT_CLOSE, "cGUI_Close", "Captured Image")
    $hPic = GUICtrlCreatePic(@ScriptDir & "\temp.jpg", 25, 25, $iX2 - $iX1 + 1, $iY2 - $iY1 + 1)
    GUISetState()
EndFunc   ;==>_Capture

Func _Edit()
    If $editValue=False Then
        $editValue=True
        GUICtrlSetData($hEdit_Button, "Stop")
    ElseIf $editValue=True Then
        $editValue=False
        GUICtrlSetData($hEdit_Button, "Edit")
    EndIf
EndFunc   ;==>_Edit

Func _Save()
    Local $scPath = @DocumentsCommonDir & "\MyScreenCaptures\"
    If Not FileExists($scPath) Then DirCreate($scPath)
    Local $savePath = FileSaveDialog("Save your screen capture", $scPath, "JPG (*.jpg)", 16, "ScreenCapture", "Captured Image")
    FileCopy(@ScriptDir & "\temp.jpg", $savePath & ".jpg", 1)
    cGUI_Close()
EndFunc   ;==>_Save

Func _Cancel()

EndFunc   ;==>_Cancel

Func mGUI_Close()
    DllClose($dc)
    FileDelete(@ScriptDir & "\temp.jpg")
    Exit
EndFunc   ;==>mGUI_Close

Func cGUI_Close()
    $editValue = False
    GUICtrlSetData($hEdit_Button, "Edit")
    GUICtrlSetState($hSave_Button, $GUI_DISABLE)
    GUICtrlSetState($hEdit_Button, $GUI_DISABLE)
    FileDelete(@ScriptDir & "\temp.jpg")
    GUIDelete("Captured Image")
EndFunc   ;==>cGUI_Close
btw, I've also noticed this script does not work with multiple monitors, why so? Edited by Wombat

Just look at us.
Everything is backwards; everything is upside down. Doctors destroy health. Lawyers destroy justice. Universities destroy knowledge. Governments destroy freedom. The major media destroy information and religions destroy spirituality. ~ Michael Ellner


The internet is our one and only hope at a truly free world, do not let them take it from us...

Share this post


Link to post
Share on other sites



Alright so I have this script that I pulled from the depths of the forum, Melba23 was the author of the original code. I changed it to meet my requirements (thank you Melba23)

I now wish to add the functionality of being able to draw on the image, as well as being able to save the edited file. Where do I start, I've scavenged, dug around and can't find any examples that help.

I'm looking for the simplest way to do this, I know I can use GDI, but I would like to avoid that if possible.

Anywho, here is the code:

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ScreenCapture.au3>
#include <Misc.au3>
#include <StaticConstants.au3>
#include <File.au3>
#include <Array.au3>

Opt("GUIOnEventMode", 1)

Global Const $SYSTEMROOT = EnvGet('systemdrive')
Global $iX1, $iY1, $iX2, $iY2, $aPos, $sMsg, $sBMP_Path, $dc
Global $editValue = False



; Create GUI
$hMain_GUI = GUICreate("Select Rectangle", 400, 50)
GUISetOnEvent($GUI_EVENT_CLOSE, "mGUI_Close", "Select Rectangle")

$hRect_Button = GUICtrlCreateButton("Capture", 10, 10, 80, 30)
GUICtrlSetOnEvent(-1, "_Capture")
$hCancel_Button = GUICtrlCreateButton("Cancel", 310, 10, 80, 30)
GUICtrlSetOnEvent(-1, "mGUI_Close")
$hEdit_Button = GUICtrlCreateButton("Edit", 110, 10, 80, 30)
GUICtrlSetState($hEdit_Button, $GUI_DISABLE)
GUICtrlSetOnEvent(-1, "_Edit")
$hSave_Button = GUICtrlCreateButton("Save", 210, 10, 80, 30)
GUICtrlSetOnEvent(-1, "_Save")
GUICtrlSetState($hSave_Button, $GUI_DISABLE)

GUISetState()

While 1

    Sleep(10)
WEnd


Func Mark_Rect()

    Local $aMouse_Pos, $hMask, $hMaster_Mask, $iTemp
    Local $UserDLL = DllOpen("user32.dll")

    Global $hRectangle_GUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
    _GUICreateInvRect($hRectangle_GUI, 0, 0, 1, 1)
    GUISetBkColor(0)
    WinSetTrans($hRectangle_GUI, "", 75)
    GUISetState(@SW_SHOW, $hRectangle_GUI)
    GUISetCursor(3, 1, $hRectangle_GUI)

    ; Wait until mouse button pressed
    While Not _IsPressed("01", $UserDLL)
        Sleep(10)
    WEnd

    ; Get first mouse position
    $aMouse_Pos = MouseGetPos()
    $iX1 = $aMouse_Pos[0]
    $iY1 = $aMouse_Pos[1]

    ; Draw rectangle while mouse button pressed
    While _IsPressed("01", $UserDLL)

        $aMouse_Pos = MouseGetPos()

        ; Set in correct order if required
        If $aMouse_Pos[0] < $iX1 Then
            $iX_Pos = $aMouse_Pos[0]
            $iWidth = $iX1 - $aMouse_Pos[0]
        Else
            $iX_Pos = $iX1
            $iWidth = $aMouse_Pos[0] - $iX1
        EndIf
        If $aMouse_Pos[1] < $iY1 Then
            $iY_Pos = $aMouse_Pos[1]
            $iHeight = $iY1 - $aMouse_Pos[1]
        Else
            $iY_Pos = $iY1
            $iHeight = $aMouse_Pos[1] - $iY1
        EndIf

        _GUICreateInvRect($hRectangle_GUI, $iX_Pos, $iY_Pos, $iWidth, $iHeight)

        Sleep(10)

    WEnd

    ; Get second mouse position
    $iX2 = $aMouse_Pos[0]
    $iY2 = $aMouse_Pos[1]

    ; Set in correct order if required
    If $iX2 < $iX1 Then
        $iTemp = $iX1
        $iX1 = $iX2
        $iX2 = $iTemp
    EndIf
    If $iY2 < $iY1 Then
        $iTemp = $iY1
        $iY1 = $iY2
        $iY2 = $iTemp
    EndIf

    GUIDelete($hRectangle_GUI)
    DllClose($UserDLL)

EndFunc   ;==>Mark_Rect

Func _GUICreateInvRect($hWnd, $iX, $iY, $iW, $iH)

    $hMask_1 = _WinAPI_CreateRectRgn(0, 0, @DesktopWidth, $iY)
    $hMask_2 = _WinAPI_CreateRectRgn(0, 0, $iX, @DesktopHeight)
    $hMask_3 = _WinAPI_CreateRectRgn($iX + $iW, 0, @DesktopWidth, @DesktopHeight)
    $hMask_4 = _WinAPI_CreateRectRgn(0, $iY + $iH, @DesktopWidth, @DesktopHeight)

    _WinAPI_CombineRgn($hMask_1, $hMask_1, $hMask_2, 2)
    _WinAPI_CombineRgn($hMask_1, $hMask_1, $hMask_3, 2)
    _WinAPI_CombineRgn($hMask_1, $hMask_1, $hMask_4, 2)

    _WinAPI_DeleteObject($hMask_2)
    _WinAPI_DeleteObject($hMask_3)
    _WinAPI_DeleteObject($hMask_4)

    _WinAPI_SetWindowRgn($hWnd, $hMask_1, 1)

EndFunc   ;==>_GUICreateInvRect

; -------------

Func _Capture()
    If WinExists("Captured Image", "") = 1 Then GUIDelete("Captured Image")
    FileDelete(@ScriptDir & "\temp.jpg")
    GUISetState(@SW_HIDE, $hMain_GUI)
    Mark_Rect()
    ; Capture selected area
    $sBMP_Path = @ScriptDir & "\temp.jpg"
    _ScreenCapture_Capture($sBMP_Path, $iX1, $iY1, $iX2, $iY2, False)
    GUISetState(@SW_SHOW, $hMain_GUI)
    WinMove("Select Rectangle", "", Default + 75, Default + 100)
    GUICtrlSetState($hSave_Button, $GUI_ENABLE)
    GUICtrlSetState($hEdit_Button, $GUI_ENABLE)
    ; Display image
    $hBitmap_GUI = GUICreate("Captured Image", $iX2 - $iX1 + 50, $iY2 - $iY1 + 50, Default, Default)
    GUISetBkColor(0x525252, "Captured Image")
    GUISetOnEvent($GUI_EVENT_CLOSE, "cGUI_Close", "Captured Image")
    $hPic = GUICtrlCreatePic(@ScriptDir & "\temp.jpg", 25, 25, $iX2 - $iX1 + 1, $iY2 - $iY1 + 1)
    GUISetState()
EndFunc   ;==>_Capture

Func _Edit()

EndFunc   ;==>_Edit

Func _Save()
    Local $scPath = @DocumentsCommonDir & "\MyScreenCaptures\"
    If Not FileExists($scPath) Then DirCreate($scPath)
    Local $savePath = FileSaveDialog("Save your screen capture", $scPath, "JPG (*.jpg)", 16, "ScreenCapture", "Captured Image")
    FileCopy(@ScriptDir & "\temp.jpg", $savePath & ".jpg", 1)
    cGUI_Close()
EndFunc   ;==>_Save

Func _Cancel()

EndFunc   ;==>_Cancel

Func mGUI_Close()
    DllClose($dc)
    FileDelete(@ScriptDir & "\temp.jpg")
    Exit
EndFunc   ;==>mGUI_Close

Func cGUI_Close()
    $editValue = False
    GUICtrlSetState($hSave_Button, $GUI_DISABLE)
    GUICtrlSetState($hEdit_Button, $GUI_DISABLE)
    FileDelete(@ScriptDir & "\temp.jpg")
    GUIDelete("Captured Image")
EndFunc   ;==>cGUI_Close

btw, I've also noticed this script does not work with multiple monitors, why so?

 

I think without using GDI/GDI+ it is not possible to modify the taken screenshot. 

I cannot remember whether this version already supports multi monitors but you can give a try -> 

Otherwise AutoIt Windows Screenshooter supports multiple monitors. ;)

Br,

UEZ

1 person likes this

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

I think without using GDI/GDI+ it is not possible to modify the taken screenshot. 

 

I cannot remember whether this version already supports multi monitors but you can give a try -> 

 

Otherwise AutoIt Windows Screenshooter supports multiple monitors. ;)

 

Br,

UEZ

Thank you UEZ, I'll look into that link... maybe GDI is the direction to take


Just look at us.
Everything is backwards; everything is upside down. Doctors destroy health. Lawyers destroy justice. Universities destroy knowledge. Governments destroy freedom. The major media destroy information and religions destroy spirituality. ~ Michael Ellner


The internet is our one and only hope at a truly free world, do not let them take it from us...

Share this post


Link to post
Share on other sites

I assume that this version is not supporting multiple monitors. I'm on holidays now for 3 weeks and I cannot test multiple monitors features yet but GDI+ should be the direction to drive.

Br,

UEZ


Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

Alright, so I solved the multiple screen issue by editing the code here:

Global $hRectangle_GUI = GUICreate("", @DesktopWidth*2, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)

and here:

$hMask_1 = _WinAPI_CreateRectRgn(0, 0, @DesktopWidth*2, $iY)
    $hMask_2 = _WinAPI_CreateRectRgn(0, 0, $iX, @DesktopHeight)
    $hMask_3 = _WinAPI_CreateRectRgn($iX + $iW, 0, @DesktopWidth*2, @DesktopHeight)
    $hMask_4 = _WinAPI_CreateRectRgn(0, $iY + $iH, @DesktopWidth*2, @DesktopHeight)

by multiplying the @DesktopWidth*2

 

I'm still looking for a way to draw directly on the captured image.


Just look at us.
Everything is backwards; everything is upside down. Doctors destroy health. Lawyers destroy justice. Universities destroy knowledge. Governments destroy freedom. The major media destroy information and religions destroy spirituality. ~ Michael Ellner


The internet is our one and only hope at a truly free world, do not let them take it from us...

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

That's not a good approach - use this instead:

$hFullScreen = WinGetHandle("[TITLE:Program Manager;CLASS:Progman]")
$aFullScreen = WinGetPos($hFullScreen)
$aFullScreen array has everything you need for multiple monitors support (not tested for 3+ monitors).

 

Unfortunatelly you cannot draw directly to a bitmap. You have to create a graphic context to the GDI+ bitmap to draw something onto the bitmap.

First you have to convert the GDI bitmap to GDI+ bitmap, then create the graphic context. Afterwards to can draw to the bitmap wrapped by the graphic context.

 

 

Try this:

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ScreenCapture.au3>
#include <Misc.au3>
#include <StaticConstants.au3>
#include <File.au3>
#include <Array.au3>

Opt("GUIOnEventMode", 1)

Global Const $SYSTEMROOT = EnvGet('systemdrive'), $STM_SETIMAGE = 0x0172, $IMAGE_BITMAP = 0
Global $iX1, $iY1, $iX2, $iY2, $aPos, $sMsg, $sBMP_Path, $dc, $hGDIPlusBitmap, $hGDIBitmap
Global $editValue = False


_GDIPlus_Startup()
; Create GUI
$hMain_GUI = GUICreate("Select Rectangle", 400, 50)
GUISetOnEvent($GUI_EVENT_CLOSE, "mGUI_Close", "Select Rectangle")

$hRect_Button = GUICtrlCreateButton("Capture", 10, 10, 80, 30)
GUICtrlSetOnEvent(-1, "_Capture")
$hCancel_Button = GUICtrlCreateButton("Cancel", 310, 10, 80, 30)
GUICtrlSetOnEvent(-1, "mGUI_Close")
$hEdit_Button = GUICtrlCreateButton("Edit", 110, 10, 80, 30)
GUICtrlSetState($hEdit_Button, $GUI_DISABLE)
GUICtrlSetOnEvent(-1, "_Edit")
$hSave_Button = GUICtrlCreateButton("Save", 210, 10, 80, 30)
GUICtrlSetOnEvent(-1, "_Save")
GUICtrlSetState($hSave_Button, $GUI_DISABLE)

GUISetState()

While 1

    Sleep(10)
WEnd


Func Mark_Rect()

    Local $aMouse_Pos, $hMask, $hMaster_Mask, $iTemp
    Local $UserDLL = DllOpen("user32.dll")

    Global $hRectangle_GUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
    _GUICreateInvRect($hRectangle_GUI, 0, 0, 1, 1)
    GUISetBkColor(0)
    WinSetTrans($hRectangle_GUI, "", 75)
    GUISetState(@SW_SHOW, $hRectangle_GUI)
    GUISetCursor(3, 1, $hRectangle_GUI)

    ; Wait until mouse button pressed
    While Not _IsPressed("01", $UserDLL)
        Sleep(10)
    WEnd

    ; Get first mouse position
    $aMouse_Pos = MouseGetPos()
    $iX1 = $aMouse_Pos[0]
    $iY1 = $aMouse_Pos[1]

    ; Draw rectangle while mouse button pressed
    While _IsPressed("01", $UserDLL)

        $aMouse_Pos = MouseGetPos()

        ; Set in correct order if required
        If $aMouse_Pos[0] < $iX1 Then
            $iX_Pos = $aMouse_Pos[0]
            $iWidth = $iX1 - $aMouse_Pos[0]
        Else
            $iX_Pos = $iX1
            $iWidth = $aMouse_Pos[0] - $iX1
        EndIf
        If $aMouse_Pos[1] < $iY1 Then
            $iY_Pos = $aMouse_Pos[1]
            $iHeight = $iY1 - $aMouse_Pos[1]
        Else
            $iY_Pos = $iY1
            $iHeight = $aMouse_Pos[1] - $iY1
        EndIf

        _GUICreateInvRect($hRectangle_GUI, $iX_Pos, $iY_Pos, $iWidth, $iHeight)

        Sleep(10)

    WEnd

    ; Get second mouse position
    $iX2 = $aMouse_Pos[0]
    $iY2 = $aMouse_Pos[1]

    ; Set in correct order if required
    If $iX2 < $iX1 Then
        $iTemp = $iX1
        $iX1 = $iX2
        $iX2 = $iTemp
    EndIf
    If $iY2 < $iY1 Then
        $iTemp = $iY1
        $iY1 = $iY2
        $iY2 = $iTemp
    EndIf

    GUIDelete($hRectangle_GUI)
    DllClose($UserDLL)

EndFunc   ;==>Mark_Rect

Func _GUICreateInvRect($hWnd, $iX, $iY, $iW, $iH)

    $hMask_1 = _WinAPI_CreateRectRgn(0, 0, @DesktopWidth, $iY)
    $hMask_2 = _WinAPI_CreateRectRgn(0, 0, $iX, @DesktopHeight)
    $hMask_3 = _WinAPI_CreateRectRgn($iX + $iW, 0, @DesktopWidth, @DesktopHeight)
    $hMask_4 = _WinAPI_CreateRectRgn(0, $iY + $iH, @DesktopWidth, @DesktopHeight)

    _WinAPI_CombineRgn($hMask_1, $hMask_1, $hMask_2, 2)
    _WinAPI_CombineRgn($hMask_1, $hMask_1, $hMask_3, 2)
    _WinAPI_CombineRgn($hMask_1, $hMask_1, $hMask_4, 2)

    _WinAPI_DeleteObject($hMask_2)
    _WinAPI_DeleteObject($hMask_3)
    _WinAPI_DeleteObject($hMask_4)

    _WinAPI_SetWindowRgn($hWnd, $hMask_1, 1)

EndFunc   ;==>_GUICreateInvRect

; -------------

Func _Capture()
    If WinExists("Captured Image", "") = 1 Then GUIDelete("Captured Image")
;~     FileDelete(@ScriptDir & "\temp.jpg")
    GUISetState(@SW_HIDE, $hMain_GUI)
    Mark_Rect()
    ; Capture selected area
;~     $sBMP_Path = @ScriptDir & "\temp.jpg"
    If $hGDIBitmap Then _WinAPI_DeleteObject($hGDIBitmap)
    $hGDIBitmap = _ScreenCapture_Capture("", $iX1, $iY1, $iX2, $iY2, False)
    If $hGDIPlusBitmap Then _GDIPlus_BitmapDispose($hGDIPlusBitmap) ;dispose ressource to avoid memory leak
    $hGDIPlusBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hGDIBitmap)
    _WinAPI_DeleteObject($hGDIBitmap) ;the GDI bitmap is not needed anymore
    Local $hGfxContext = _GDIPlus_ImageGetGraphicsContext($hGDIPlusBitmap)
    _GDIPlus_GraphicsDrawString($hGfxContext, "AutoIt rulez!", 0, 0, "Arial", 20)
    _GDIPlus_GraphicsDispose($hGfxContext)
    $hGDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hGDIPlusBitmap) ;create GDI bitmap to send it to the pic control later
    GUISetState(@SW_SHOW, $hMain_GUI)
    WinMove("Select Rectangle", "", Default + 75, Default + 100)
    GUICtrlSetState($hSave_Button, $GUI_ENABLE)
    GUICtrlSetState($hEdit_Button, $GUI_ENABLE)
    ; Display image
    $hBitmap_GUI = GUICreate("Captured Image", $iX2 - $iX1 + 50, $iY2 - $iY1 + 50, Default, Default)
    GUISetBkColor(0x525252, "Captured Image")
    GUISetOnEvent($GUI_EVENT_CLOSE, "cGUI_Close", "Captured Image")
    $hPic = GUICtrlCreatePic("", 25, 25, $iX2 - $iX1 + 1, $iY2 - $iY1 + 1)
    _WinAPI_DeleteObject(GUICtrlSendMsg($hPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hGDIBitmap))
    GUISetState()
EndFunc   ;==>_Capture

Func _Edit()
    If $editValue=False Then
        $editValue=True
        GUICtrlSetData($hEdit_Button, "Stop")
    ElseIf $editValue=True Then
        $editValue=False
        GUICtrlSetData($hEdit_Button, "Edit")
    EndIf
EndFunc   ;==>_Edit

Func _Save()
    Local $scPath = @DocumentsCommonDir & "\MyScreenCaptures\"
    If Not FileExists($scPath) Then DirCreate($scPath)
    Local $savePath = FileSaveDialog("Save your screen capture", $scPath, "JPG (*.jpg)", 16, "ScreenCapture", "Captured Image")
;~     FileCopy(@ScriptDir & "\temp.jpg", $savePath & ".jpg", 1)
    _GDIPlus_ImageSaveToFile($hGDIPlusBitmap, $savePath & ".jpg")
    cGUI_Close()
EndFunc   ;==>_Save

Func _Cancel()

EndFunc   ;==>_Cancel

Func mGUI_Close()
    DllClose($dc)
;~     FileDelete(@ScriptDir & "\temp.jpg")
    If $hGDIPlusBitmap Then _GDIPlus_BitmapDispose($hGDIPlusBitmap)
    If $hGDIBitmap Then _WinAPI_DeleteObject($hGDIBitmap)
    _GDIPlus_Shutdown()
    Exit
EndFunc   ;==>mGUI_Close

Func cGUI_Close()
    $editValue = False
    GUICtrlSetData($hEdit_Button, "Edit")
    GUICtrlSetState($hSave_Button, $GUI_DISABLE)
    GUICtrlSetState($hEdit_Button, $GUI_DISABLE)
;~     FileDelete(@ScriptDir & "\temp.jpg")
    GUIDelete("Captured Image")
EndFunc   ;==>cGUI_Close
Edit: forgot to dispose the GDI bitmap to avoid memory leak.

Br,

UEZ

Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

What did i do wrong here? I'm honestly lost... and tired sorry :/

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ScreenCapture.au3>
#include <Misc.au3>
#include <StaticConstants.au3>
#include <File.au3>
#include <Array.au3>

Opt("GUIOnEventMode", 1)

Global Const $SYSTEMROOT = EnvGet('systemdrive'), $STM_SETIMAGE = 0x0172, $IMAGE_BITMAP = 0
Global $iX1, $iY1, $iX2, $iY2, $aPos, $sMsg, $sBMP_Path, $dc, $hGDIPlusBitmap, $hGDIBitmap, $hPic

Global $editValue = False


_GDIPlus_Startup()
; Create GUI
$hMain_GUI = GUICreate("Select Rectangle", 400, 50)
GUISetOnEvent($GUI_EVENT_CLOSE, "mGUI_Close", "Select Rectangle")

$hRect_Button = GUICtrlCreateButton("Capture", 10, 10, 80, 30)
GUICtrlSetOnEvent(-1, "_Capture")
$hCancel_Button = GUICtrlCreateButton("Cancel", 310, 10, 80, 30)
GUICtrlSetOnEvent(-1, "mGUI_Close")
$hEdit_Button = GUICtrlCreateButton("Edit", 110, 10, 80, 30)
GUICtrlSetState($hEdit_Button, $GUI_DISABLE)
GUICtrlSetOnEvent(-1, "_Edit")
$hSave_Button = GUICtrlCreateButton("Save", 210, 10, 80, 30)
GUICtrlSetOnEvent(-1, "_Save")
GUICtrlSetState($hSave_Button, $GUI_DISABLE)

GUISetState()

While 1

    Sleep(10)
WEnd


Func Mark_Rect()

    Local $aMouse_Pos, $hMask, $hMaster_Mask, $iTemp
    Local $UserDLL = DllOpen("user32.dll")

    Global $hRectangle_GUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
    _GUICreateInvRect($hRectangle_GUI, 0, 0, 1, 1)
    GUISetBkColor(0)
    WinSetTrans($hRectangle_GUI, "", 75)
    GUISetState(@SW_SHOW, $hRectangle_GUI)
    GUISetCursor(3, 1, $hRectangle_GUI)

    ; Wait until mouse button pressed
    While Not _IsPressed("01", $UserDLL)
        Sleep(10)
    WEnd

    ; Get first mouse position
    $aMouse_Pos = MouseGetPos()
    $iX1 = $aMouse_Pos[0]
    $iY1 = $aMouse_Pos[1]

    ; Draw rectangle while mouse button pressed
    While _IsPressed("01", $UserDLL)

        $aMouse_Pos = MouseGetPos()

        ; Set in correct order if required
        If $aMouse_Pos[0] < $iX1 Then
            $iX_Pos = $aMouse_Pos[0]
            $iWidth = $iX1 - $aMouse_Pos[0]
        Else
            $iX_Pos = $iX1
            $iWidth = $aMouse_Pos[0] - $iX1
        EndIf
        If $aMouse_Pos[1] < $iY1 Then
            $iY_Pos = $aMouse_Pos[1]
            $iHeight = $iY1 - $aMouse_Pos[1]
        Else
            $iY_Pos = $iY1
            $iHeight = $aMouse_Pos[1] - $iY1
        EndIf

        _GUICreateInvRect($hRectangle_GUI, $iX_Pos, $iY_Pos, $iWidth, $iHeight)

        Sleep(10)

    WEnd

    ; Get second mouse position
    $iX2 = $aMouse_Pos[0]
    $iY2 = $aMouse_Pos[1]

    ; Set in correct order if required
    If $iX2 < $iX1 Then
        $iTemp = $iX1
        $iX1 = $iX2
        $iX2 = $iTemp
    EndIf
    If $iY2 < $iY1 Then
        $iTemp = $iY1
        $iY1 = $iY2
        $iY2 = $iTemp
    EndIf

    GUIDelete($hRectangle_GUI)
    DllClose($UserDLL)

EndFunc   ;==>Mark_Rect

Func _GUICreateInvRect($hWnd, $iX, $iY, $iW, $iH)

    $hMask_1 = _WinAPI_CreateRectRgn(0, 0, @DesktopWidth, $iY)
    $hMask_2 = _WinAPI_CreateRectRgn(0, 0, $iX, @DesktopHeight)
    $hMask_3 = _WinAPI_CreateRectRgn($iX + $iW, 0, @DesktopWidth, @DesktopHeight)
    $hMask_4 = _WinAPI_CreateRectRgn(0, $iY + $iH, @DesktopWidth, @DesktopHeight)

    _WinAPI_CombineRgn($hMask_1, $hMask_1, $hMask_2, 2)
    _WinAPI_CombineRgn($hMask_1, $hMask_1, $hMask_3, 2)
    _WinAPI_CombineRgn($hMask_1, $hMask_1, $hMask_4, 2)

    _WinAPI_DeleteObject($hMask_2)
    _WinAPI_DeleteObject($hMask_3)
    _WinAPI_DeleteObject($hMask_4)

    _WinAPI_SetWindowRgn($hWnd, $hMask_1, 1)

EndFunc   ;==>_GUICreateInvRect

; -------------

Func _Capture()
    If WinExists("Captured Image", "") = 1 Then GUIDelete("Captured Image")
;~     FileDelete(@ScriptDir & "\temp.jpg")
    GUISetState(@SW_HIDE, $hMain_GUI)
    Mark_Rect()
    ; Capture selected area
;~     $sBMP_Path = @ScriptDir & "\temp.jpg"
    If $hGDIBitmap Then _WinAPI_DeleteObject($hGDIBitmap)
    $hGDIBitmap = _ScreenCapture_Capture("", $iX1, $iY1, $iX2, $iY2, False)
    If $hGDIPlusBitmap Then _GDIPlus_BitmapDispose($hGDIPlusBitmap) ;dispose ressource to avoid memory leak
    $hGDIPlusBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hGDIBitmap)
    _WinAPI_DeleteObject($hGDIBitmap) ;the GDI bitmap is not needed anymore
    Local $hGfxContext = _GDIPlus_ImageGetGraphicsContext($hGDIPlusBitmap)
    _GDIPlus_GraphicsDispose($hGfxContext)
    $hGDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hGDIPlusBitmap) ;create GDI bitmap to send it to the pic control later
    GUISetState(@SW_SHOW, $hMain_GUI)
    WinMove("Select Rectangle", "", Default + 75, Default + 100)
    GUICtrlSetState($hSave_Button, $GUI_ENABLE)
    GUICtrlSetState($hEdit_Button, $GUI_ENABLE)
    ; Display image
    $hBitmap_GUI = GUICreate("Captured Image", $iX2 - $iX1 + 50, $iY2 - $iY1 + 50, Default, Default)
    GUISetBkColor(0x525252, "Captured Image")
    GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "_Paint", "Captured Image")
    GUISetOnEvent($GUI_EVENT_CLOSE, "cGUI_Close", "Captured Image")
    $hPic = GUICtrlCreatePic("", 25, 25, $iX2 - $iX1 + 1, $iY2 - $iY1 + 1)
    _WinAPI_DeleteObject(GUICtrlSendMsg($hPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hGDIBitmap))
    GUIRegisterMsg($WM_PAINT, "WM_PAINT")
    GUISetState()
EndFunc   ;==>_Capture

Func _Paint()
    If $editValue=True Then
            Do

        $cPos = GUIGetCursorInfo()
        _GDIPlus_GraphicsFillRect($hPic, $cPos[0] - 1, $cPos[1] - 1, 7, 5)

        ;don't wait for the processing of the GUI
        _Winapi_PostMessage($hGDIPlusBitmap, $WM_PAINT, 0, 0)

    Until Not $cPos[2]
    Else
        Sleep(10)
    EndIf
EndFunc

Func _Edit()
    If $editValue=False Then
        $editValue=True
        GUICtrlSetData($hEdit_Button, "Stop")
    ElseIf $editValue=True Then
        $editValue=False
        GUICtrlSetData($hEdit_Button, "Edit")
    EndIf
EndFunc   ;==>_Edit

Func _Save()
    Local $scPath = @DocumentsCommonDir & "\MyScreenCaptures\"
    If Not FileExists($scPath) Then DirCreate($scPath)
    Local $savePath = FileSaveDialog("Save your screen capture", $scPath, "JPG (*.jpg)", 16, "ScreenCapture", "Captured Image")
;~     FileCopy(@ScriptDir & "\temp.jpg", $savePath & ".jpg", 1)
    _GDIPlus_ImageSaveToFile($hGDIPlusBitmap, $savePath & ".jpg")
    cGUI_Close()
EndFunc   ;==>_Save

Func _Cancel()

EndFunc   ;==>_Cancel

Func mGUI_Close()
    DllClose($dc)
;~     FileDelete(@ScriptDir & "\temp.jpg")
    If $hGDIPlusBitmap Then _GDIPlus_BitmapDispose($hGDIPlusBitmap)
    If $hGDIBitmap Then _WinAPI_DeleteObject($hGDIBitmap)
    _GDIPlus_Shutdown()
    Exit
EndFunc   ;==>mGUI_Close

Func cGUI_Close()
    $editValue = False
    GUICtrlSetData($hEdit_Button, "Edit")
    GUICtrlSetState($hSave_Button, $GUI_DISABLE)
    GUICtrlSetState($hEdit_Button, $GUI_DISABLE)
;~     FileDelete(@ScriptDir & "\temp.jpg")
    GUIDelete("Captured Image")
EndFunc   ;==>cGUI_Close

Func WM_PAINT($hWnd, $iMsg, $wParam, $lParam)

    ;paint the buffer image on the GUI.
    _GDIPlus_GraphicsDrawImage($hGDIPlusBitmap, $hPic, 0, 0)

EndFunc   ;==>WM_PAINT

Just look at us.
Everything is backwards; everything is upside down. Doctors destroy health. Lawyers destroy justice. Universities destroy knowledge. Governments destroy freedom. The major media destroy information and religions destroy spirituality. ~ Michael Ellner


The internet is our one and only hope at a truly free world, do not let them take it from us...

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