#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Icon=Resources\icon.ico #AutoIt3Wrapper_Compression=4 #AutoIt3Wrapper_Res_Description=Visual Image Crop #AutoIt3Wrapper_Res_Fileversion=1.0.0.4 #AutoIt3Wrapper_Res_LegalCopyright=GreenCan #AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 #Tidy_Parameters=/gd 1 /gds 1 /nsdp #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include-once #include #include #include #include #include Opt('MustDeclareVars', 1) Opt("MouseCoordMode", 2) ; 2=client ; #FUNCTION# ==================================================================================================== ; Name...........: _CropImage ; Description....: Visual Crop Tool ; Syntax.........: _CropImage($sFileName[, $bMagnifier = False[, $bCrosshair = True[, $iWidth = -1[, $iHeight = -1[, $iLeft = -1[, $iTop = -1[, $iRatioW = 0[, $iRatioH = 0[, $iStyle = -1[, $iExStyle = -1[, $iParent = 0]]]]]]]]]]]) ; Parameters ....: $sFileName - Image filename to be cropped ; $bMagnifier - Optional: Shows magnifier if True (default = False) ; $bCrosshair - Optional: Shows Crosshair if True (default = True) ; $iWidth - Optional: Width of Crop GUI, Ddfault is Image size or best fit (default = -1) ; $iHeight - Optional: Height of Crop GUI, Ddfault is Image size or best fit (default = -1) ; $iLeft - Optional: Left position of Crop GUI, default is centered (default = -1) ; $iTop - Optional: Top position of Crop GUI, default is centered (default = -1) ; $iRatioW - Optional: Ratio Width of Crop rectangle, 0 is no ratio (default = 0) ; $iRatioH - Optional: Ratio Height of Crop rectangle, 0 is no ratio (default = 0) ; $iStyle - Optional: Defines the style of the GUI (as per GUICreate) (default = -1) ; $iExStyle - Optional: Defines the extended style of the GUI (as per GUICreate) (default = -1) ; $iParent - Optional: The handle of another previously created GUI window (as per GUICreate) (default = 0) ; Return values .: Success - Returns Cropped file name ; Failure - Returns empty file name and sets @error: ; |1 - Failed to crop file ; |2 - Ratio Height = 0 and Ratio Width > 0 or vice versa ; |3 - Quit without saving ; Authors........: GreenCan ; Modified ......: ; Remarks .......: All Styles and Extended Styles have not been tested ; ; Related .......: ; Link ..........: ; Example .......: Yes ; =============================================================================================================== Func _CropImage($sFileName, $bMagnifier = False, $bCrosshair = True, $iWidth = -1, $iHeight = -1, $iLeft = -1, $iTop = -1, $iRatioW = 0, $iRatioH = 0, $iStyle = -1, $iExStyle = -1, $iParent = 0) If ($iRatioH = 0 And $iRatioW > 0) Or ($iRatioW = 0 And $iRatioH > 0) Then Return SetError(2, 0, "") Local $hCropGUI, $hGraphicGUI, $hBMPBuff, $hBitmap_Scaled, $hGraphic, $iImageWidth, $iImageHeight Local $hFileMenu, $hSaveBtn, $hCloseBtn, $hMagnifierMenu, $hMagnifier, $hBitmap_original, $hPenRed, $hPenBlack, $msg, $sNewFilename Local $iOriginalWidth, $bRectangleDrawn = False, $bResized = False, $iScale = 1, $aWinPos, $iError = 0 Local $iMenuHeight = _WinAPI_GetSystemMetrics($SM_CYMENU) ; The height of a single-line menu bar, in pixels. Local $iBorderWidth = _WinAPI_GetSystemMetrics($SM_CYDLGFRAME) * 2 Local $iCaptionHeight = _WinAPI_GetSystemMetrics($SM_CYCAPTION) Local $aStartMousePos, $aCurrMousePos, $iRectangleWidth, $iRectangleHeight, $iRectangleLeft, $iRectangleTop Local $aCurrMoveMousePos, $aKeepCurrMoveMousePos[2] = [0,0]; move variables Local $bDefaultCursor = True, $hLabel, $iCursor, $bSizeAll = False Local $iSizeCorner = 4, $bUpperLeft = False, $bUpperRight = False, $bLowerLeft = False, $bLowerRight = False _GDIPlus_Startup() $hBitmap_original = _GDIPlus_ImageLoadFromFile($sFileName) ;Create an image object based on a file $iImageWidth = _GDIPlus_ImageGetWidth($hBitmap_original) $iImageHeight = _GDIPlus_ImageGetHeight($hBitmap_original) ;If Not @Compiled Then ConsoleWrite(@ScriptLineNumber & " " & $iImageWidth & " x " & $iImageHeight & @CRLF) $iOriginalWidth = $iImageWidth $hCropGUI = GUICreate("Crop " & StringRegExpReplace($sFileName, ".*\\", "") & " [" & $iImageWidth & "x" & $iImageHeight & "]", ( $iWidth = -1 ? @DesktopWidth : $iWidth ), ( $iHeight = -1 ? @DesktopHeight - 100 : $iHeight ) , $iLeft, $iTop, $iStyle, $iExStyle, $iParent) $hLabel = GUICtrlCreateLabel("", 0, 0, ( $iWidth = -1 ? @DesktopWidth : $iWidth ), ( $iHeight = -1 ? @DesktopHeight - 100 : $iHeight )) $hFileMenu = GUICtrlCreateMenu("&File") $hSaveBtn = GUICtrlCreateMenuItem("&Save Image ()", $hFileMenu) $hCloseBtn = GUICtrlCreateMenuItem("Close Window", $hFileMenu) $hMagnifierMenu = GUICtrlCreateMenu("Magnifier") $hMagnifier = GUICtrlCreateMenuItem("Magnifier On (F2 or Ctrl-M)", $hMagnifierMenu) ; Set accelerators for Magnifier Local $aAccellerators[2][2] = [["^m", $hMagnifier],["{F2}", $hMagnifier]] ; F2 or Ctrl-m GUISetAccelerators($aAccellerators) Local $iClientWidth = _WinAPI_GetClientWidth($hCropGUI), $iClientHeight = _WinAPI_GetClientHeight($hCropGUI) ;create a resized image in the GUI if the pictures is bigger than GUI Client size If $iImageWidth > $iClientWidth Then $iImageHeight = Round($iClientWidth / $iImageWidth * $iImageHeight, 0) $iImageWidth = $iClientWidth $bResized = True EndIf If $iImageHeight > ($iClientHeight - $iMenuHeight) Then $iImageWidth = Round(($iClientHeight - $iMenuHeight) / $iImageHeight * $iImageWidth, 0) $iImageHeight = ($iClientHeight - $iMenuHeight) $bResized = True EndIf $iScale = ($iImageWidth/$iOriginalWidth) ;If Not @Compiled Then ConsoleWrite(@ScriptLineNumber & " scaled size: " & $iImageWidth & " x " & $iImageHeight & " scale: " & $iScale & @CRLF) ; autosize option If $iWidth = -1 Then $aWinPos = WinGetPos($hCropGUI) If $iLeft = -1 Then $iLeft = (@DesktopWidth - $iImageWidth + $iBorderWidth)/2 WinMove( $hCropGUI, "", $iLeft, $aWinPos[1], $iImageWidth + $iBorderWidth ) EndIf If $iHeight = -1 Then $aWinPos = WinGetPos($hCropGUI) If $iTop = -1 Then $iTop = (@DesktopHeight - 150 - $iImageHeight + $iMenuHeight + $iBorderWidth + $iCaptionHeight)/2 WinMove( $hCropGUI, "", $aWinPos[0], $iTop, $aWinPos[2], $iImageHeight + $iMenuHeight + $iBorderWidth + $iCaptionHeight) EndIf ; if ratio, change GUI title content If $iRatioW > 0 Then WinSetTitle($hCropGUI, "", "Crop " & StringRegExpReplace($sFileName, ".*\\", "") & " [" & $iImageWidth & "x" & $iImageHeight & "] - Crop Ratio: [" & $iRatioW & "x" & $iRatioH & "]") ; Display image If $bResized Then $hBitmap_Scaled = _GDIPlus_ImageScale($hBitmap_original, $iScale, $iScale) ; not showing in GUI Else $hBitmap_Scaled = $hBitmap_original EndIf $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hCropGUI) ;create a graphics object from a window handle _GDIPlus_GraphicsDrawImage($hGraphic, $hBitmap_Scaled, 0, 0) ;display scaled image $hPenRed = _GDIPlus_PenCreate(0xFFFF0000, 1) ; red rectangle _GDIPlus_PenSetDashStyle($hPenRed, $GDIP_DASHSTYLEDASH ) ; set red dash line $hPenBlack = _GDIPlus_PenCreate(0xFF000000, 1) ; black crosshair $hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hCropGUI) $hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($iImageWidth, $iImageHeight, $hGraphicGUI) $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff) _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hBitmap_Scaled, 0, 0, $iImageWidth, $iImageHeight, 0, 0, $iImageWidth, $iImageHeight) #Region Magnifier GUI (Melba23) Local $hMag_Win = GUICreate("MAG", 100, 100, $iImageWidth/2, $iImageHeight/2, $WS_POPUP, $WS_EX_TOPMOST) If $bMagnifier Then GUISetState(@SW_SHOW, $hMag_Win) Local $hMag_GUI = WinGetHandle("MAG") ; Get device context for Mag GUI Local $hMagDC = _WinAPI_GetDC($hMag_GUI) If @error Then Exit ; Get device context for desktop Local $hDeskDC = _WinAPI_GetDC(0) If @error Then _WinAPI_ReleaseDC($hMag_GUI, $hMagDC) Exit EndIf ; Create pen Local $hPen = _WinAPI_CreatePen($PS_SOLID, 5, 0x7E7E7E) Local $oObj = _WinAPI_SelectObject($hMagDC, $hPen) #EndRegion Magnifier GUI GUISetState(@SW_SHOW , $hCropGUI) MouseMove($iImageWidth/2 ,$iImageHeight/2, 1) ; positions mouse in center of GUI $iCursor = MouseGetCursor() _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE, $hCloseBtn ; Clear up Mag GUI _WinAPI_SelectObject($hMagDC, $oObj) _WinAPI_DeleteObject($hPen) _WinAPI_ReleaseDC(0, $hDeskDC) _WinAPI_ReleaseDC($hMag_GUI, $hMagDC) GUIDelete($hMag_GUI) _GDIPlus_PenDispose($hPenRed) _GDIPlus_PenDispose($hPenBlack) _GDIPlus_ImageDispose($hBitmap_Scaled) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_GraphicsDispose($hGraphicGUI) _WinAPI_DeleteObject($hBMPBuff) _GDIPlus_Shutdown() GUIDelete($hCropGUI) Return SetError(3, 0, "") Case $hSaveBtn ; also with Enter If IsArray($aStartMousePos) Then $sNewFilename = _SaveCrop($sFileName, $hBitmap_original, $aStartMousePos, $iRectangleWidth, $iRectangleHeight, $iScale) If @error Then $iError = @error _GDIPlus_PenDispose($hPenRed) _GDIPlus_PenDispose($hPenBlack) _GDIPlus_ImageDispose($hBitmap_Scaled) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_GraphicsDispose($hGraphicGUI) _WinAPI_DeleteObject($hBMPBuff) _GDIPlus_Shutdown() GUIDelete($hCropGUI) Return SetError($iError, 0, $sNewFilename) EndIf Case $hMagnifier If $bRectangleDrawn Then ContinueCase ; no Magnifier if rectangle is already drawn If $bMagnifier Then $bMagnifier = False GUISetState(@SW_HIDE, $hMag_Win) WinActivate($hCropGUI) Else $bMagnifier = True Loupe(MouseGetPos(), WinGetPos($hCropGUI), $hMag_GUI, $iMenuHeight + $iBorderWidth + $iCaptionHeight, $iBorderWidth, $hMagDC, $hDeskDC) GUISetState(@SW_SHOW, $hMag_Win) WinActivate($hCropGUI) EndIf EndSwitch If WinActive($hCropGUI) And $bCrosshair And Not $bRectangleDrawn Then ; crosshair only if no rectangle drawn yet $aStartMousePos = MouseGetPos() ;mouse Start Position ; only show Magnifier if mouse is over the image If $bMagnifier And _ $aStartMousePos[0] > 0 and $aStartMousePos[0] < $iImageWidth And $aStartMousePos[1] > 0 and $aStartMousePos[1] < $iImageHeight Then Loupe($aStartMousePos, WinGetPos($hCropGUI), $hMag_GUI, $iMenuHeight + $iBorderWidth + $iCaptionHeight, $iBorderWidth, $hMagDC, $hDeskDC) EndIf _GDIPlus_GraphicsClear($hGraphic, 0xFFE8FFE8) _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hBitmap_Scaled, 0, 0, $iImageWidth, $iImageHeight, 0, 0, $iImageWidth, $iImageHeight) _GDIPlus_GraphicsDrawLine ( $hGraphic, 0, $aStartMousePos[1], $iImageWidth, $aStartMousePos[1], $hPenBlack) _GDIPlus_GraphicsDrawLine ( $hGraphic, $aStartMousePos[0], 0, $aStartMousePos[0], $iImageHeight, $hPenBlack) _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) Sleep(10) EndIf If WinActive($hCropGUI) And _IsPressed("01") And ($bDefaultCursor Or $bUpperLeft Or $bUpperRight Or $bLowerLeft Or $bLowerRight) Then ; left mouse button and default cursor or any of corners, draw rectangle ; corner sizing, position $aStartMousePos at the oposite side of the active corner If $bUpperLeft Then $aStartMousePos[0] = $iRectangleLeft + $iRectangleWidth $aStartMousePos[1] = $iRectangleTop + $iRectangleHeight ElseIf $bUpperRight Then $aStartMousePos[0] = $iRectangleLeft $aStartMousePos[1] = $iRectangleTop + $iRectangleHeight ElseIf $bLowerLeft Then $aStartMousePos[0] = $iRectangleLeft + $iRectangleWidth $aStartMousePos[1] = $iRectangleTop ElseIf $bLowerRight Then $aStartMousePos[0] = $iRectangleLeft $aStartMousePos[1] = $iRectangleTop Else $aStartMousePos = MouseGetPos() ;mouse Start Position If $bMagnifier Then GUISetState(@SW_SHOW, $hMag_Win) ; show Magnifier again WinActivate($hCropGUI) EndIf EndIf Do Sleep(10) $aCurrMousePos = MouseGetPos() ; mouse current position ; don't draw if mouse is not moving If $aCurrMousePos[0] = $aKeepCurrMoveMousePos[0] And $aCurrMousePos[1] = $aKeepCurrMoveMousePos[1] Then ContinueLoop If $bMagnifier and $iRatioW = 0 Then ; only show Magnifier if mouse is over the image If $aCurrMousePos[0] > 0 and $aCurrMousePos[0] < $iImageWidth And $aCurrMousePos[1] > 0 and $aCurrMousePos[1] < $iImageHeight Then _ Loupe($aCurrMousePos, WinGetPos($hCropGUI), $hMag_GUI, $iMenuHeight + $iBorderWidth + $iCaptionHeight, $iBorderWidth, $hMagDC, $hDeskDC) Else GUISetState(@SW_HIDE, $hMag_Win) ; hide Magnifier because with ratio, doesn't make sense EndIf ; check edge boundaries If $iRatioW > 0 Then ; ratio to be respected $iRectangleLeft = ($aCurrMousePos[0] < $aStartMousePos[0] ? $aCurrMousePos[0] : $aStartMousePos[0]) $iRectangleTop = Round($aCurrMousePos[1] < $aStartMousePos[1] ? $aStartMousePos[1] - Abs(($aCurrMousePos[0] - $aStartMousePos[0]) / $iRatioW * $iRatioH) : $aStartMousePos[1]) $iRectangleWidth = Abs($aCurrMousePos[0] - $aStartMousePos[0]) $iRectangleHeight = Round(Abs(($aCurrMousePos[0] - $aStartMousePos[0]) / $iRatioW * $iRatioH)) If $iRectangleLeft + $iRectangleWidth > $iImageWidth Then ; over right edge $iRectangleLeft = $aStartMousePos[0] $iRectangleWidth = $iImageWidth - $aStartMousePos[0] ; max width from left edge to starting point If $aCurrMousePos[1] < $aStartMousePos[1] Then $iRectangleTop = $aStartMousePos[1] - Round($iRectangleWidth / $iRatioW * $iRatioH) If $iRectangleTop < 0 Then ContinueLoop EndIf $iRectangleHeight = Round($iRectangleWidth / $iRatioW * $iRatioH) If $iRectangleTop + $iRectangleHeight > $iImageHeight Then ContinueLoop ElseIf $iRectangleLeft < 0 Then ; over left edge $iRectangleLeft = 0 $iRectangleWidth = $aStartMousePos[0] ; max width from left edge to starting point If $aCurrMousePos[1] < $aStartMousePos[1] Then $iRectangleTop = $aStartMousePos[1] - Round($iRectangleWidth / $iRatioW * $iRatioH) If $iRectangleTop < 0 Then ContinueLoop EndIf $iRectangleHeight = Round($iRectangleWidth / $iRatioW * $iRatioH) If $iRectangleTop + $iRectangleHeight > $iImageHeight Then ContinueLoop ElseIf $iRectangleTop + $iRectangleHeight > $iImageHeight Then ; over lower edge $iRectangleHeight = $iImageHeight - $iRectangleTop $iRectangleWidth = Round($iRectangleHeight / $iRatioH * $iRatioW) If $iRectangleLeft < $aStartMousePos[0] - $iRectangleWidth Then $iRectangleLeft = $aStartMousePos[0] - $iRectangleWidth ElseIf $iRectangleTop < 0 Then ; over upper edge $iRectangleTop = 0 $iRectangleHeight = $aStartMousePos[1] ;$iImageHeight - $iRectangleTop $iRectangleWidth = Round($iRectangleHeight / $iRatioH * $iRatioW) If $iRectangleLeft < $aStartMousePos[0] - $iRectangleWidth Then $iRectangleLeft = $aStartMousePos[0] - $iRectangleWidth EndIf Else ; free ratio If $aCurrMousePos[0] > $iImageWidth Then $aCurrMousePos[0] = $iImageWidth ElseIf $aCurrMousePos[0] < 0 Then $aCurrMousePos[0] = 0 ElseIf $aCurrMousePos[1] > $iImageHeight Then $aCurrMousePos[1] = $iImageHeight ElseIf $aCurrMousePos[1] < 0 Then $aCurrMousePos[1] = 0 EndIf $iRectangleLeft = ($aCurrMousePos[0] < $aStartMousePos[0] ? $aCurrMousePos[0] : $aStartMousePos[0]) $iRectangleTop = Round($aCurrMousePos[1] < $aStartMousePos[1] ? $aStartMousePos[1] - Abs($aCurrMousePos[1] - $aStartMousePos[1]) : $aStartMousePos[1]) $iRectangleWidth = Abs($aCurrMousePos[0] - $aStartMousePos[0]) $iRectangleHeight = Round(Abs($aCurrMousePos[1] - $aStartMousePos[1])) EndIf _GDIPlus_GraphicsClear($hGraphic, 0xFFE8FFE8) _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hBitmap_Scaled, 0, 0, $iImageWidth, $iImageHeight, 0, 0, $iImageWidth, $iImageHeight) _GDIPlus_GraphicsDrawRect($hGraphic, $iRectangleLeft, $iRectangleTop, $iRectangleWidth, $iRectangleHeight, $hPenRed) _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) $aKeepCurrMoveMousePos = $aCurrMousePos ; keep for next boundary run check Until Not _IsPressed("01") If $iRectangleWidth > 0 And $iRectangleHeight > 0 Then ; draw size corners _GDIPlus_GraphicsDrawRect($hGraphic, $iRectangleLeft - $iSizeCorner, $iRectangleTop - $iSizeCorner, $iSizeCorner * 2, $iSizeCorner * 2, $hPenRed) _GDIPlus_GraphicsDrawRect($hGraphic, $iRectangleLeft + $iRectangleWidth - $iSizeCorner, $iRectangleTop - $iSizeCorner, $iSizeCorner * 2, $iSizeCorner * 2, $hPenRed) _GDIPlus_GraphicsDrawRect($hGraphic, $iRectangleLeft - $iSizeCorner, $iRectangleTop + $iRectangleHeight - $iSizeCorner, $iSizeCorner * 2, $iSizeCorner * 2, $hPenRed) _GDIPlus_GraphicsDrawRect($hGraphic, $iRectangleLeft + $iRectangleWidth - $iSizeCorner, $iRectangleTop + $iRectangleHeight - $iSizeCorner, $iSizeCorner * 2, $iSizeCorner * 2, $hPenRed) _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) $bRectangleDrawn = True EndIf If $bMagnifier Then GUISetState(@SW_HIDE, $hMag_Win) ; hide Magnifier WinActivate($hCropGUI) EndIf If Not @Compiled Then ConsoleWrite(@ScriptLineNumber & " " & $iRectangleLeft & " x " & $iRectangleTop & " - " & $iRectangleWidth & " x " & $iRectangleHeight & @CRLF) ElseIf WinActive($hCropGUI) And Not $bRectangleDrawn And Not $bDefaultCursor Then ; rectangle is erased, set default cursor again GUICtrlSetCursor($hLabel, $iCursor) ; set back to default mouse cursor $bDefaultCursor = True $bUpperLeft = False $bUpperRight = False $bLowerLeft = False $bLowerRight = False $bSizeAll = False #Region sizing corner area ElseIf WinActive($hCropGUI) And $bRectangleDrawn And (Not $bUpperRight) And _ ; rectangle is drawn, set Size cursor if over upper right size corner (MouseGetPos(0) >= $iRectangleLeft + $iRectangleWidth - $iSizeCorner And MouseGetPos(0) <= $iRectangleLeft + $iRectangleWidth + $iSizeCorner) And _ (MouseGetPos(1) >= $iRectangleTop - $iSizeCorner And MouseGetPos(1) <= $iRectangleTop + $iSizeCorner) Then GUICtrlSetCursor($hLabel, 10) ; mouse SIZENESW cursor $bUpperRight = True $bDefaultCursor = False $bSizeAll = False ElseIf WinActive($hCropGUI) And $bRectangleDrawn And $bUpperRight And _ ; rectangle is drawn, set default cursor if leaving upper right size corner Not ((MouseGetPos(0) >= $iRectangleLeft + $iRectangleWidth - $iSizeCorner And MouseGetPos(0) <= $iRectangleLeft + $iRectangleWidth + $iSizeCorner) And _ (MouseGetPos(1) >= $iRectangleTop - $iSizeCorner And MouseGetPos(1) <= $iRectangleTop + $iSizeCorner)) Then GUICtrlSetCursor($hLabel, $iCursor) ; mouse default cursor $bUpperRight = False $bDefaultCursor = True $bSizeAll = False ElseIf WinActive($hCropGUI) And $bRectangleDrawn And (Not $bUpperLeft) And _ ; rectangle is drawn, set Size cursor if over upper left size corner (MouseGetPos(0) >= $iRectangleLeft - $iSizeCorner And MouseGetPos(0) <= $iRectangleLeft + $iSizeCorner) And _ (MouseGetPos(1) >= $iRectangleTop - $iSizeCorner And MouseGetPos(1) <= $iRectangleTop + $iSizeCorner) Then GUICtrlSetCursor($hLabel, 12) ; mouse SIZENWSE cursor $bUpperLeft = True $bDefaultCursor = False $bSizeAll = False ElseIf WinActive($hCropGUI) And $bRectangleDrawn And $bUpperLeft And _ ; rectangle is drawn, set default cursor if leaving upper left size corner Not ((MouseGetPos(0) >= $iRectangleLeft - $iSizeCorner And MouseGetPos(0) <= $iRectangleLeft + $iSizeCorner) And _ (MouseGetPos(1) >= $iRectangleTop - $iSizeCorner And MouseGetPos(1) <= $iRectangleTop + $iSizeCorner)) Then GUICtrlSetCursor($hLabel, $iCursor) ; mouse default cursor $bUpperLeft = False $bDefaultCursor = True $bSizeAll = False ElseIf WinActive($hCropGUI) And $bRectangleDrawn And (Not $bLowerLeft) And _ ; rectangle is drawn, set Size cursor if over lower left size corner (MouseGetPos(0) >= $iRectangleLeft - $iSizeCorner And MouseGetPos(0) <= $iRectangleLeft + $iSizeCorner) And _ (MouseGetPos(1) >= $iRectangleTop + $iRectangleHeight - $iSizeCorner And MouseGetPos(1) <= $iRectangleTop + $iRectangleHeight+ $iSizeCorner) Then GUICtrlSetCursor($hLabel, 10) ; mouse SIZENESW cursor $bLowerLeft = True $bDefaultCursor = False $bSizeAll = False ElseIf WinActive($hCropGUI) And $bRectangleDrawn And $bLowerLeft And _ ; rectangle is drawn, set default cursor if leaving lower left size corner Not ((MouseGetPos(0) >= $iRectangleLeft - $iSizeCorner And MouseGetPos(0) <= $iRectangleLeft + $iSizeCorner) And _ (MouseGetPos(1) >= $iRectangleTop + $iRectangleHeight - $iSizeCorner And MouseGetPos(1) <= $iRectangleTop + $iRectangleHeight+ $iSizeCorner)) Then GUICtrlSetCursor($hLabel, $iCursor) ; mouse default cursor $bLowerLeft = False $bDefaultCursor = True $bSizeAll = False ElseIf WinActive($hCropGUI) And $bRectangleDrawn And (Not $bLowerRight) And _ ; rectangle is drawn, set Size cursor if over lower right size corner (MouseGetPos(0) >= $iRectangleLeft + $iRectangleWidth - $iSizeCorner And MouseGetPos(0) <= $iRectangleLeft + $iRectangleWidth + $iSizeCorner) And _ (MouseGetPos(1) >= $iRectangleTop + $iRectangleHeight - $iSizeCorner And MouseGetPos(1) <= $iRectangleTop + $iRectangleHeight+ $iSizeCorner) Then GUICtrlSetCursor($hLabel, 12) ; mouse SIZENWSE cursor $bLowerRight = True $bDefaultCursor = False $bSizeAll = False ElseIf WinActive($hCropGUI) And $bRectangleDrawn And $bLowerRight And _ ; rectangle is drawn, set Size cursor if over lower right size corner Not ((MouseGetPos(0) >= $iRectangleLeft + $iRectangleWidth - $iSizeCorner And MouseGetPos(0) <= $iRectangleLeft + $iRectangleWidth + $iSizeCorner) And _ (MouseGetPos(1) >= $iRectangleTop + $iRectangleHeight - $iSizeCorner And MouseGetPos(1) <= $iRectangleTop + $iRectangleHeight+ $iSizeCorner)) Then GUICtrlSetCursor($hLabel, $iCursor) ; mouse default cursor $bLowerRight = False $bDefaultCursor = True $bSizeAll = False #EndRegion sizing corner area #Region move ElseIf WinActive($hCropGUI) And $bRectangleDrawn And Not $bSizeAll And _ ; rectangle is drawn, set 'move' cursor if over upper left rectangle (Not $bUpperLeft) And (Not $bUpperRight) And (Not $bLowerLeft) And (Not $bLowerRight) And _ (MouseGetPos(0) > $iRectangleLeft And MouseGetPos(0) < $iRectangleLeft + $iRectangleWidth) And _ (MouseGetPos(1) > $iRectangleTop And MouseGetPos(1) < $iRectangleTop + $iRectangleHeight) Then GUICtrlSetCursor($hLabel, 9) ; mouse SizeAll cursor $bDefaultCursor = False $bSizeAll = True ElseIf WinActive($hCropGUI) And $bRectangleDrawn And Not $bDefaultCursor And _ ; rectangle is drawn, default cursor if not over rectangle (Not $bUpperLeft) And (Not $bUpperRight) And (Not $bLowerLeft) And (Not $bLowerRight) And _ Not ((MouseGetPos(0) > $iRectangleLeft And MouseGetPos(0) < $iRectangleLeft + $iRectangleWidth) And _ (MouseGetPos(1) > $iRectangleTop And MouseGetPos(1) < $iRectangleTop + $iRectangleHeight)) Then GUICtrlSetCursor($hLabel, $iCursor) ; set back to default mouse cursor $bDefaultCursor = True $bSizeAll = False $bUpperLeft = False $bUpperRight = False $bLowerLeft = False $bLowerRight = False ElseIf WinActive($hCropGUI) And _IsPressed("01") And $bRectangleDrawn And Not $bDefaultCursor Then ; left mouse button and rectangle drawn, move rectangle $aCurrMoveMousePos = MouseGetPos() ;mouse Start Position $aKeepCurrMoveMousePos = $aCurrMoveMousePos Do Sleep(10) $aCurrMoveMousePos = MouseGetPos() ; mouse current position ; don't draw if mouse is not moving If $aCurrMoveMousePos[0] = $aKeepCurrMoveMousePos[0] And $aCurrMoveMousePos[1] = $aKeepCurrMoveMousePos[1] Then ContinueLoop $iRectangleLeft = $iRectangleLeft + $aCurrMoveMousePos[0] - $aKeepCurrMoveMousePos[0] $iRectangleTop = $iRectangleTop + $aCurrMoveMousePos[1] - $aKeepCurrMoveMousePos[1] ; check boundaries If $iRectangleLeft + $iRectangleWidth > $iImageWidth Then ; over right edge $iRectangleLeft = $iImageWidth - $iRectangleWidth If $aCurrMoveMousePos[0] > $iImageWidth Then ; don't let the mouse pointer get outside of the image boundaries $aCurrMoveMousePos[0] = $iImageWidth MouseMove($iImageWidth - 1, $aCurrMoveMousePos[1], 1) EndIf ElseIf $iRectangleLeft < 0 Then ; over left edge $iRectangleLeft = 0 If $aCurrMoveMousePos[0] < 0 Then ; don't let the mouse pointer get outside of the image boundaries $aCurrMoveMousePos[0] = 0 MouseMove(0, $aCurrMoveMousePos[1], 1) EndIf EndIf If $iRectangleTop + $iRectangleHeight > $iImageHeight Then ; over lower edge $iRectangleTop = $iImageHeight - $iRectangleHeight If $aCurrMoveMousePos[1] > $iImageHeight Then ; don't let the mouse pointer get outside of the image boundaries $aCurrMoveMousePos[1] = $iImageHeight MouseMove($aCurrMoveMousePos[0], $iImageHeight - 1, 1) EndIf ElseIf $iRectangleTop < 0 Then ; over upper edge $iRectangleTop = 0 If $aCurrMoveMousePos[1] < 0 Then ; don't let the mouse pointer get outside of the image boundaries $aCurrMoveMousePos[1] = 0 MouseMove($aCurrMoveMousePos[0], 0, 1) EndIf EndIf $aKeepCurrMoveMousePos = $aCurrMoveMousePos ; keep for next boundary run check _GDIPlus_GraphicsClear($hGraphic, 0xFFE8FFE8) _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hBitmap_Scaled, 0, 0, $iImageWidth, $iImageHeight, 0, 0, $iImageWidth, $iImageHeight) _GDIPlus_GraphicsDrawRect($hGraphic, $iRectangleLeft, $iRectangleTop, $iRectangleWidth, $iRectangleHeight, $hPenRed) _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) ;If Not @Compiled Then ConsoleWrite(@ScriptLineNumber & " " & $iRectangleLeft & " x " & $iRectangleTop & " - " & $iRectangleWidth & " x " & $iRectangleHeight & @CRLF) Until Not _IsPressed("01") If Not @Compiled Then ConsoleWrite(@ScriptLineNumber & " " & $iRectangleLeft & " x " & $iRectangleTop & " - " & $iRectangleWidth & " x " & $iRectangleHeight & @CRLF) ; draw size corners _GDIPlus_GraphicsDrawRect($hGraphic, $iRectangleLeft - $iSizeCorner, $iRectangleTop - $iSizeCorner, $iSizeCorner * 2, $iSizeCorner * 2, $hPenRed) _GDIPlus_GraphicsDrawRect($hGraphic, $iRectangleLeft + $iRectangleWidth - $iSizeCorner, $iRectangleTop - $iSizeCorner, $iSizeCorner * 2, $iSizeCorner * 2, $hPenRed) _GDIPlus_GraphicsDrawRect($hGraphic, $iRectangleLeft - $iSizeCorner, $iRectangleTop + $iRectangleHeight - $iSizeCorner, $iSizeCorner * 2, $iSizeCorner * 2, $hPenRed) _GDIPlus_GraphicsDrawRect($hGraphic, $iRectangleLeft + $iRectangleWidth - $iSizeCorner, $iRectangleTop + $iRectangleHeight - $iSizeCorner, $iSizeCorner * 2, $iSizeCorner * 2, $hPenRed) _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) #Region move ElseIf WinActive($hCropGUI) And _IsPressed("02") Then ; right mouse button, erase rectangle $bRectangleDrawn = False _GDIPlus_GraphicsClear($hGraphic, 0xFFE8FFE8) _GDIPlus_GraphicsDrawImageRectRect($hGraphic, $hBitmap_Scaled, 0, 0, $iImageWidth, $iImageHeight, 0, 0, $iImageWidth, $iImageHeight) _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) If $bMagnifier Then GUISetState(@SW_SHOW, $hMag_Win) ; show Magnifier again WinActivate($hCropGUI) EndIf ElseIf WinActive($hCropGUI) And _IsPressed("0D") And $bRectangleDrawn Then ; enter, save crop If IsArray($aStartMousePos) Then $sNewFilename = _SaveCrop($sFileName, $hBitmap_original, $iRectangleLeft, $iRectangleTop, $iRectangleWidth, $iRectangleHeight, $iScale) If @error Then $iError = @error _GDIPlus_PenDispose($hPenRed) _GDIPlus_PenDispose($hPenBlack) _GDIPlus_ImageDispose($hBitmap_Scaled) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_GraphicsDispose($hGraphicGUI) _WinAPI_DeleteObject($hBMPBuff) _GDIPlus_Shutdown() GUIDelete($hCropGUI) Return SetError($iError, 0, $sNewFilename) EndIf EndIf WEnd EndFunc ;==>_CropImage Func _SaveCrop($sFileName, $hBitmap_original, $iRectangleLeft, $iRectangleTop, $iRectangleWidth, $iRectangleHeight, $iScale = 1) ; this function crops the original loaded bitmap If Not @Compiled Then ConsoleWrite(@ScriptLineNumber & " " & $iScale & " " & $iRectangleLeft & " x " & $iRectangleTop & " - " & $iRectangleWidth & " x " & $iRectangleHeight & @CRLF) Local $hClone, $iError = 0 Local $sImageDir = StringLeft($sFileName, StringInStr($sFileName, "\", 0, -1) - 1) Local $sFileExtension = StringTrimLeft($sFileName, StringInStr($sFileName, ".", 0, -1)) Local $sImageFileName = StringTrimRight(StringRight($sFileName, StringLen($sFileName) - StringInStr($sFileName, "\", 0, -1)), StringLen($sFileExtension)+1) Local $sNewFilename = $sImageDir & "\" & $sImageFileName & "_cr" & "." & $sFileExtension FileDelete($sNewFilename) ; if exists, delete it $hClone = _GDIPlus_BitmapCloneArea($hBitmap_original, $iRectangleLeft / $iScale, $iRectangleTop / $iScale, $iRectangleWidth / $iScale, $iRectangleHeight / $iScale, $GDIP_PXF32ARGB) _GDIPlus_ImageSaveToFile($hClone, $sNewFilename) ; strange error handling with this function, not consistent! checking if file exists, that is at least correct If Not FileExists($sNewFilename) Then $iError = 1 $sNewFilename = "" EndIf _WinAPI_DeleteObject($hClone) Return SetError($iError, 0, $sNewFilename) EndFunc ;==>_SaveCrop ;~ Func _SaveCropFromFile($sFileName, $iRectangleLeft, $iRectangleTop, $iRectangleWidth, $iRectangleHeight, $iScale = 1) ;~ ; this function loads the image file and crops it ;~ Local $sImageDir = StringLeft($sFileName, StringInStr($sFileName, "\", 0, -1) - 1) ;~ Local $sFileExtension = StringTrimLeft($sFileName, StringInStr($sFileName, ".", 0, -1)) ;~ Local $sImageFileName = StringTrimRight(StringRight($sFileName, StringLen($sFileName) - StringInStr($sFileName, "\", 0, -1)), StringLen($sFileExtension)+1) ;~ Local $sNewFilename = $sImageDir & "\" & $sImageFileName & "_filecr" & "." & $sFileExtension ;~ Local $hBmp = _GDIPlus_ImageLoadFromFile($sFileName) ;~ Local $h_Bmp_Ret = _GDIPlus_BitmapCreateFromScan0($iRectangleWidth / $iScale, $iRectangleHeight / $iScale) ;~ Local $h_Bmp_Ret_Gfx = _GDIPlus_ImageGetGraphicsContext($h_Bmp_Ret) ;~ _GDIPlus_GraphicsDrawImageRectRect($h_Bmp_Ret_Gfx, $hBmp, $iRectangleLeft / $iScale, $iRectangleTop / $iScale, $iRectangleWidth / $iScale, $iRectangleHeight / $iScale, 0, 0, $iRectangleWidth / $iScale, $iRectangleHeight / $iScale) ;~ _GDIPlus_GraphicsDispose($h_Bmp_Ret_Gfx) ;~ _GDIPlus_ImageDispose($hBmp) ;~ _GDIPlus_ImageSaveToFile($h_Bmp_Ret, $sNewFilename) ;~ $h_Bmp_Ret = 0 ;~ EndFunc ;==>_SaveCropFromFile ;~ Func _SaveCropSmall($sFileName, $hBitmap_Scaled, $iRectangleLeft, $iRectangleTop, $iRectangleWidth, $iRectangleHeight) ;~ ; this function will crop from screen size, OK for screen capture ;~ Local $hClone ;~ Local $sImageDir = StringLeft($sFileName, StringInStr($sFileName, "\", 0, -1) - 1) ;~ Local $sFileExtension = StringTrimLeft($sFileName, StringInStr($sFileName, ".", 0, -1)) ;~ Local $sImageFileName = StringTrimRight(StringRight($sFileName, StringLen($sFileName) - StringInStr($sFileName, "\", 0, -1)), StringLen($sFileExtension)+1) ;~ Local $sNewFilename = $sImageDir & "\" & $sImageFileName & "_smallcr" & "." & $sFileExtension ;~ FileDelete($sNewFilename) ; if exists, delete it ;~ $hClone = _GDIPlus_BitmapCloneArea($hBitmap_Scaled, $iRectangleLeft, $iRectangleTop, $iRectangleWidth, $iRectangleHeight, $GDIP_PXF32ARGB) ;~ _GDIPlus_ImageSaveToFile($hClone, $sNewFilename) ;~ _WinAPI_DeleteObject($hClone) ;~ EndFunc ;==>_SaveCropSmall Func Loupe($aMouse_Pos, $aWinPos, $hMag_GUI, $iClientTop, $iClientLeft, $hMagDC, $hDeskDC) ; original function by Melba23 ; https://www.autoitscript.com/forum/topic/108344-solved-how-to-zoom-in-on-a-part-of-the-screen-without-creating-a-new-window/?do=findComment&comment=763487 ; modified to accomodate the client mouse coordinates Local $iX, $iY ; Fill Mag GUI with 5x expanded contents of desktop area (10 pixels around mouse) DllCall("gdi32.dll", "int", "StretchBlt", _ "int", $hMagDC, "int", 0, "int", 0, "int", 100, "int", 100, _ "int", $hDeskDC, "int", $aWinPos[0] + $iClientLeft + $aMouse_Pos[0] - 10, "int", $aWinPos[1] + $iClientTop + $aMouse_Pos[1] - 10, "int", 20, "int", 20, _ "long", $SRCCOPY) ; Keep Mag GUI on screen If $aMouse_Pos[0] < (@DesktopWidth - 120) Then $iX = $aWinPos[0] + $iClientLeft + $aMouse_Pos[0] + 20 Else $iX = $aWinPos[0] + $iClientLeft + $aMouse_Pos[0] - 120 EndIf If $aMouse_Pos[1] < (@DesktopHeight - 150) Then $iY = $aWinPos[1] + $iClientTop + $aMouse_Pos[1] + 20 Else $iY = $aWinPos[1] + $iClientTop + $aMouse_Pos[1] - 120 EndIf WinMove($hMag_GUI, "", $iX, $iY, 100, 100) EndFunc ;==>Loupe