Zoldex Posted November 24, 2012 Posted November 24, 2012 This is my attempt on loading and let the user select only a portion of an image.I found some samples by Melba23 and UEZ and tried to glue things together.I think I've almost done it but still have some problems:Resizing and displaying image is not always proportional (just try the script with different resolution images, expecially big ones)The rectangle selection to crop is wrong: it actually selects a different region of the screen Function _GUICtrlStatic_SetImage does not work. Temporarily fixed using _WinAPI_DeleteObject instead...Any hint would be greatly appreciated!expandcollapse popup#include <GuiConstantsEx.au3> #include <WindowsConstants.au3> #Include <ScreenCapture.au3> #Include <Misc.au3> #include <StaticConstants.au3> Global $iX1, $iY1, $iX2, $iY2, $aPos, $sMsg, $sBMP_Path Global Const $IMAGE_BITMAP = 0 ; Needed for GUICtrlSendMsg. Global Const $STM_SETIMAGE = 0x0172 ; Needed for GUICtrlSendMsg. Local $GUIimg_title,$GUIwidth,$GUIheight,$GUILeft,$GUITop Local $filename = FileOpenDialog("Select image", @ScriptDir, "Image (*.jpg;*.bmp)", 3) $GUIimg_title = $filename _GDIPlus_Startup() Local $imagefromfile = _GDIPlus_ImageLoadFromFile($filename) ;Create an image object based on a file [OK] **NOTA PER LA ROTAZIONE VEDI HELP FILE!** Local $GUIwidth = _GDIPlus_ImageGetWidth ($imagefromfile) Local $GUIheight = _GDIPlus_ImageGetHeight ($imagefromfile) ;try to create a smaller window if the pictures is bigger than Desktop If $GUIwidth > @DesktopWidth Then $GUIwidth = @DesktopWidth - 6 EndIf If $GUIheight > @DesktopHeight Then $GUIheight = @DesktopHeight - 73 ; rought attempt to show the window bar... EndIf $GUILeft = (@DesktopWidth - $GUIwidth) / 2 $GUITop = (@DesktopHeight - $GUIheight) / 2 $hBitmap_resized = _GDIPlus_ScaleImage($imagefromfile, $GUIwidth, $GUIheight); attempts to scale the image but it not always proportional.. _GDIPlus_ImageDispose($imagefromfile) ; Display image $hBitmap_GUI = GUICreate($GUIimg_title & " [" & $GUIwidth & "x" & $GUIheight & "]", $GUIwidth, $GUIheight,$GUILeft,$GUITop) $hPic = GUICtrlCreatePic("", 0, 0, $GUIwidth, $GUIheight) GUISetState() Local $hHBitmap_resized = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_resized); creates an handle _WinAPI_DeleteObject(GUICtrlSendMsg($hPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap_resized)) ; Updates the GUI - It works instead of _GDIPlus_ImageDispose($hHBitmap_resized) [OK] _WinAPI_DeleteObject($hHBitmap_resized) ;~ _GUICtrlStatic_SetImage($hPic, $hBitmap_resized); does not seems to work... using _WinAPI_DeleteObject above _GDIPlus_Shutdown() ; Create GUI ;~ Local $GUITop = $hMain_GUI = GUICreate("Select a function", 480, 50) $hRect_Button = GUICtrlCreateButton("Crop", 10, 10, 80, 30) $hRot_90_plus_Button = GUICtrlCreateButton("+90°", 95, 10, 50, 30) $hRot_90_minus_Button = GUICtrlCreateButton("-90°", 150, 10, 50, 30) $hOK_Button = GUICtrlCreateButton("OK", 305, 10, 50, 30) $hCancel_Button = GUICtrlCreateButton("Cancel", 360, 10, 80, 30) GUISetState() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE, $hCancel_Button FileDelete(@ScriptDir & "Rect.bmp") Exit Case $hRect_Button GUISetState(@SW_HIDE, $hMain_GUI) Mark_Rect($GUIwidth,$GUIheight,$GUILeft,$GUITop);selects wrong area!! ; Capture selected area $sBMP_Path = @ScriptDir & "Rect.bmp" ;~ _ScreenCapture_Capture($sBMP_Path, $iX1, $iY1, $iX2, $iY2, False) _ScreenCapture_CaptureWnd($sBMP_Path, $hBitmap_GUI,$iX1, $iY1, $iX2, $iY2, False) GUISetState(@SW_SHOW, $hMain_GUI) GUIDelete($hBitmap_GUI) ; Display image $hBitmap_GUI = GUICreate("Selected Rectangle", $iX2 - $iX1 + 1, $iY2 - $iY1 + 1, 100, 100) $hPic = GUICtrlCreatePic(@ScriptDir & "Rect.bmp", 0, 0, $iX2 - $iX1 + 1, $iY2 - $iY1 + 1) GUISetState() case $hRot_90_plus_Button ; Rotate +90 case $hRot_90_minus_Button ;Rotate -90 case $hOK_Button ;should return the resulting picture object EndSwitch WEnd ; ------------- Func Mark_Rect($width = @DesktopWidth, $height = @DesktopHeight, $Left = 0, $Top = 0);Made by Melba23 - Arguments added by me Local $aMouse_Pos, $hMask, $hMaster_Mask, $iTemp Local $UserDLL = DllOpen("user32.dll") Global $hRectangle_GUI = GUICreate("", $width, $height, $Left, $Top, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST);create fading _GUICreateInvRect($hRectangle_GUI, 0, 0, 1, 1) GUISetBkColor(0) WinSetTrans($hRectangle_GUI, "", 95) 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 Func _GDIPlus_ScaleImage($hImage, $iW, $iH, $iInterpolationMode = 7) ;coded by UEZ 2012 Local $hBitmap = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iW, "int", $iH, "int", 0, "int", 0x0026200A, "ptr", 0, "int*", 0) If @error Then Return SetError(3, 0, 0) $hBitmap = $hBitmap[6] Local $hBmpCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap) DllCall($ghGDIPDll, "uint", "GdipSetInterpolationMode", "handle", $hBmpCtxt, "int", $iInterpolationMode) _GDIPlus_GraphicsDrawImageRect($hBmpCtxt, $hImage, 0, 0, $iW, $iH) _GDIPlus_ImageDispose($hImage) _GDIPlus_GraphicsDispose($hBmpCtxt) Return $hBitmap EndFunc Func _GUICtrlStatic_SetImage($iCtrlId, $hBitmap) Local Const $STM_SETIMAGE = 0x0172 Local Const $IMAGE_BITMAP = 0 Local Const $SS_BITMAP = 0xE Local Const $GWL_STYLE = -16 If IsHWnd($iCtrlId) Then If WinGetProcess($iCtrlId) <> @AutoItPID Then Return SetError(1,0,0) Else $iCtrlId = GUICtrlGetHandle($iCtrlId) If Not $iCtrlId Then Return SetError(2,0,0) EndIf ; set SS_BITMAP style to control Local $oldStyle = DllCall("user32.dll", "long", "GetWindowLong", "hwnd", $iCtrlId, "int", $GWL_STYLE) If @error Then Return SetError(3, 0, 0) DllCall("user32.dll", "long", "SetWindowLong", "hwnd", $iCtrlId, "int", $GWL_STYLE, "long", BitOR($oldStyle[0], $SS_BITMAP)) If @error Then Return SetError(4, 0, 0) Local $oldBmp = DllCall("user32.dll", "handle", "SendMessageW", "hwnd", $iCtrlId, "int", $STM_SETIMAGE, "wparam", $IMAGE_BITMAP, "handle", $hBitmap) If @error Then Return SetError(5, 0, 0) If $oldBmp[0] Then _WinAPI_DeleteObject($oldBmp[0]) Return 1 EndFunc
PlayHD Posted November 24, 2012 Posted November 24, 2012 _GDIPlus_BitmapCloneArea could be another solution instead of _ScreenCapture_CaptureWnd My UDF : _WinShake, _WinSplitMy Apps : Google Guitar Bot, PuzzleGameDesign Gui : Interesting Tabs Design, RBox Project (abandoned), Animated Gui on Exit
PhoenixXL Posted November 24, 2012 Posted November 24, 2012 use _WinAPI_GetSystemMetrics to get the TitleBar and the Border dimensions My code: PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners. MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.
PhoenixXL Posted November 24, 2012 Posted November 24, 2012 Its better to Use only one GUI to carry out your Functions If you use more than one then take care that you use GuiGetMsg(1) orelse it will cause problems !! My code: PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners. MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.
PhoenixXL Posted November 24, 2012 Posted November 24, 2012 (edited) This draws the right rectangleexpandcollapse popup#include <GuiConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> #include <ScreenCapture.au3> #include <Misc.au3> #include <StaticConstants.au3> Global $iX1, $iY1, $iX2, $iY2, $aPos, $sMsg, $sBMP_Path Global Const $IMAGE_BITMAP = 0 ; Needed for GUICtrlSendMsg. Global Const $STM_SETIMAGE = 0x0172 ; Needed for GUICtrlSendMsg. Global Const $sysHeight = _WinAPI_GetSystemMetrics(4) Global Const $sysWidth = _WinAPI_GetSystemMetrics(7) Global Const $sysdHeifht = _WinAPI_GetSystemMetrics(8) Local $GUIimg_title, $GUIwidth, $GUIheight, $GUILeft, $GUITop Local $filename = FileOpenDialog("Select image", @ScriptDir, "Image (*.jpg;*.bmp)", 3) If @error Then Exit 1 $GUIimg_title = $filename _GDIPlus_Startup() Local $imagefromfile = _GDIPlus_ImageLoadFromFile($filename) ;Create an image object based on a file [OK] **NOTA PER LA ROTAZIONE VEDI HELP FILE!** Local $GUIwidth = _GDIPlus_ImageGetWidth($imagefromfile) Local $GUIheight = _GDIPlus_ImageGetHeight($imagefromfile) ;try to create a smaller window if the pictures is bigger than Desktop If $GUIwidth > @DesktopWidth Then $GUIwidth = @DesktopWidth - 6 EndIf If $GUIheight > @DesktopHeight Then $GUIheight = @DesktopHeight - 73 ; rought attempt to show the window bar... EndIf $GUILeft = (@DesktopWidth - $GUIwidth) / 2 $GUITop = (@DesktopHeight - $GUIheight) / 2 $hBitmap_resized = _GDIPlus_ScaleImage($imagefromfile, $GUIwidth, $GUIheight); attempts to scale the image but it not always proportional.. _GDIPlus_ImageDispose($imagefromfile) ; Display image $hBitmap_GUI = GUICreate($GUIimg_title & " [" & $GUIwidth & "x" & $GUIheight & "]", $GUIwidth + 50, $GUIheight + 50 + 100, $GUILeft, $GUITop) $hPic = GUICtrlCreatePic("", 25, 25 + 100, $GUIwidth, $GUIheight) GUISetState() Local $hHBitmap_resized = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_resized); creates an handle _WinAPI_DeleteObject(GUICtrlSendMsg($hPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBitmap_resized)) ; Updates the GUI - It works instead of _GDIPlus_ImageDispose($hHBitmap_resized) [OK] _WinAPI_DeleteObject($hHBitmap_resized) _GDIPlus_Shutdown() $hRect_Button = GUICtrlCreateButton("Crop", 25, 25, 80, 30) $hRot_90_plus_Button = GUICtrlCreateButton("+90°", 145, 25, 50, 30) $hRot_90_minus_Button = GUICtrlCreateButton("-90°", 245, 25, 50, 30) GUISetState() While 1 Switch GUIGetMsg() Case -3 ; Case $hRect_Button $pPos = WinGetPos($hBitmap_GUI) Mark_Rect($GUIwidth, $GUIheight, $pPos[0] + 25 + $sysWidth, $pPos[1] + 125 + $sysHeight + $sysdHeifht);selects wrong area!! GUISwitch($hBitmap_GUI) EndSwitch WEnd ; ------------- Func Mark_Rect($width = @DesktopWidth, $height = @DesktopHeight, $Left = 0, $Top = 0);Made by Melba23 - Arguments added by me Local $aMouse_Pos, $hMask, $hMaster_Mask, $iTemp Local $UserDLL = DllOpen("user32.dll") Global $hRectangle_GUI = GUICreate("", $width, $height, $Left, $Top, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST);create fading _GUICreateInvRect($hRectangle_GUI, 0, 0, 1, 1) GUISetBkColor(0) WinSetTrans($hRectangle_GUI, "", 95) 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 _GDIPlus_ScaleImage($hImage, $iW, $iH, $iInterpolationMode = 7) ;coded by UEZ 2012 Local $hBitmap = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromScan0", "int", $iW, "int", $iH, "int", 0, "int", 0x0026200A, "ptr", 0, "int*", 0) If @error Then Return SetError(3, 0, 0) $hBitmap = $hBitmap[6] Local $hBmpCtxt = _GDIPlus_ImageGetGraphicsContext($hBitmap) DllCall($ghGDIPDll, "uint", "GdipSetInterpolationMode", "handle", $hBmpCtxt, "int", $iInterpolationMode) _GDIPlus_GraphicsDrawImageRect($hBmpCtxt, $hImage, 0, 0, $iW, $iH) _GDIPlus_ImageDispose($hImage) _GDIPlus_GraphicsDispose($hBmpCtxt) Return $hBitmap EndFunc ;==>_GDIPlus_ScaleImage Edited November 24, 2012 by PhoenixXL My code: PredictText: Predict Text of an Edit Control Like Scite. Remote Gmail: Execute your Scripts through Gmail. StringRegExp:Share and learn RegExp.Run As System: A command line wrapper around PSEXEC.exe to execute your apps scripts as System (LSA). Database: An easier approach for _SQ_LITE beginners. MathsEx: A UDF for Fractions and LCM, GCF/HCF. FloatingText: An UDF for make your text floating. Clipboard Extendor: A clipboard monitoring tool. Custom ScrollBar: Scroll Bar made with GDI+, user can use bitmaps instead. RestrictEdit_SRE: Restrict text in an Edit Control through a Regular Expression.
Zoldex Posted November 24, 2012 Author Posted November 24, 2012 This draws the right rectangleYes, it does.But the crop function does not...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now