tip Posted October 10, 2011 Share Posted October 10, 2011 (edited) Hi to all, Recently I've been trying to create a routine to ScreenCapture a window, apply a blur effect to the captured image, return the blurred image bitmap handle and finally apply that bitmap to a PicCtrl using _SetBitmapToCtrl function. (I believe it is written by Zedna.) But I'm having hard time understanding how the GDI+ functions exactly work. I had found several blur effect scripts on the forum. One script has very gaussian-blur-like effect but it applies final bitmap directly to window(_WinAPI_GetDC etc.), the other one returns final bitmaps handle but the effect isn't as realistic imho. First one is written by Siao, can be found here: and the second one is written by UEZ, can be found here I've tried to integrate these two script and failed Here is the last draft:expandcollapse popup#include <GDIPlus.au3> #include <GUIConstantsEx.au3> #Include <ScreenCapture.au3> _Main() Func _WindowCapture_Blurred($i_HWND1) Local $sRatio = 3, $iInterMode = 7, $iPixOffsetMode = 2, $iSmoothMode = 7 Local $tip_WindowClientInfo = _WinGetClientPos_Ex($i_HWND1,True) _GDIPlus_Startup() Local $hScreenCapture = _ScreenCapture_Capture("", $tip_WindowClientInfo[0],$tip_WindowClientInfo[1],$tip_WindowClientInfo[0]+$tip_WindowClientInfo[2],$tip_WindowClientInfo[1]+$tip_WindowClientInfo[3], False) Local $hBitmapBig = _GDIPlus_BitmapCreateFromHBITMAP($hScreenCapture) Local $hBitmapSmall = _GDIPlus_BitmapCloneArea($hBitmapBig, 0, 0, $tip_WindowClientInfo[2]/$sRatio, $tip_WindowClientInfo[3]/$sRatio) Local $hGraphicSmall = _GDIPlus_ImageGetGraphicsContext($hBitmapSmall) Local $hGraphicBig = _GDIPlus_GraphicsCreateFromHWND(_WinAPI_GetDesktopWindow()) ;~ ;http://msdn2.microsoft.com/en-us/library/ms534141(VS.85).aspx ;~ ;InterpolationModeDefault = 0 ;~ ;InterpolationModeLowQuality = 1 ;~ ;InterpolationModeHighQuality = 2 ;~ ;InterpolationModeBilinear = 3 ;~ ;InterpolationModeBicubic = 4 ;~ ;InterpolationModeNearestNeighbor = 5 ;~ ;InterpolationModeHighQualityBilinear = 6 ;~ ;InterpolationModeHighQualityBicubic = 7 DllCall("gdiplus.dll", "int", "GdipSetInterpolationMode", "hwnd", $hGraphicBig, "int", $iInterMode) DllCall("gdiplus.dll", "int", "GdipSetInterpolationMode", "hwnd", $hGraphicSmall, "int", $iInterMode) ;~ ;http://msdn2.microsoft.com/en-us/library/ms534169(VS.85).aspx ;~ ;PixelOffsetModeDefault = 0 = PixelOffsetModeNone ;~ ;PixelOffsetModeHighSpeed = 1 = PixelOffsetModeNone ;~ ;PixelOffsetModeHighQuality = 2 = PixelOffsetModeHalf ;~ ;PixelOffsetModeNone = 3 ;~ ;PixelOffsetModeHalf = 4 DllCall("gdiplus.dll", "int", "GdipSetPixelOffsetMode", "hwnd", $hGraphicBig, "int", $iPixOffsetMode) DllCall("gdiplus.dll", "int", "GdipSetPixelOffsetMode", "hwnd", $hGraphicSmall, "int", $iPixOffsetMode) ;~ ;http://msdn2.microsoft.com/en-us/library/ms534173(VS.85).aspx ;~ ;SmoothingModeDefault = 0 = SmoothingModeNone ;~ ;SmoothingModeHighSpeed = 1 = SmoothingModeNone ;~ ;SmoothingModeHighQuality = 2 = SmoothingModeAntiAlias8x4 ;~ ;SmoothingModeNone ;~ ;SmoothingModeAntiAlias8x4 ;~ ;SmoothingModeAntiAlias = SmoothingModeAntiAlias8x4 ;~ ;SmoothingModeAntiAlias8x8 DllCall("gdiplus.dll", "int", "GdipSetSmoothingMode", "hwnd", $hGraphicBig, "int", $iSmoothMode) DllCall("gdiplus.dll", "int", "GdipSetSmoothingMode", "hwnd", $hGraphicSmall, "int", $iSmoothMode) _GDIPlus_GraphicsDrawImageRect($hGraphicSmall, $hBitmapBig, 0, 0, $tip_WindowClientInfo[2], $tip_WindowClientInfo[3]) _GDIPlus_GraphicsDrawImageRect($hGraphicBig, $hBitmapSmall, 0, 0, $tip_WindowClientInfo[2] / $sRatio, $tip_WindowClientInfo[3] / $sRatio) $aRet = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmapBig) _WinAPI_DeleteObject($hScreenCapture) _GDIPlus_GraphicsDispose($hGraphicSmall) _GDIPlus_GraphicsDispose($hGraphicBig) _GDIPlus_BitmapDispose($hBitmapSmall) _GDIPlus_BitmapDispose($hBitmapBig) _GDIPlus_Shutdown() Return $aRet EndFunc Func _Main() $Form1 = GUICreate("WindowCapture_Blurred Tryout", 640, 540, (@DesktopWidth-640)/2, (@DesktopHeight-560)/2) GUISetFont(10, 400, 0, "Segoe UI" ,$Form1,5) GUICtrlSetDefBkColor(-2,$Form1) GUISetBkColor(0x000000,$Form1) $MenuItem1 = GUICtrlCreateMenu("&File") $MenuItem2 = GUICtrlCreateMenuItem("Exit", $MenuItem1) $Label1 = GUICtrlCreateLabel(" Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." _ & " Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute" _ & " irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat" _ & " cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." & @CRLF & @CRLF & " Suspendisse potenti. Fusce semper consequat suscipit. Quisque porttitor est eu felis pharetra lacinia. Donec mauris massa, aliquet " _ & "vitae consectetur quis, laoreet in dolor. Cras fermentum vestibulum nulla, eget sollicitudin elit porttitor id. Nunc sapien nulla, blandit " _ & "pellentesque sollicitudin et, dignissim non justo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. " _ & "Vivamus congue ligula sed diam vehicula suscipit.", 30, 60, 580, 200) GUICtrlSetColor(-1, 0xFFFFFF) $Button1 = GUICtrlCreateButton("Try", 240, 300, 120, 25) GUISetState(@SW_SHOW) While 1 $nMsg = GUIGetMsg() Switch $nMsg Case -3, $MenuItem2 ; -3=$GUI_EVENT_CLOSE ExitLoop Case $Button1 $a = _WinGetClientPos_Ex($Form1,True) $GUI2 = GUICreate("",$a[2],$a[3],$a[0]+$a[2],$a[1]) $PicCtl = GUICtrlCreatePic("",0,0,$a[2],$a[3]) $BlurredSS = _WindowCapture_Blurred($Form1) GUISetState() _SetBitmapToCtrl($PicCtl,$BlurredSS) EndSwitch WEnd EndFunc Func _SetBitmapToCtrl($CtrlId, $hBitmap) Local Const $STM_SETIMAGE = 0x0172 Local Const $IMAGE_BITMAP = 0 Local Const $SS_BITMAP = 0xE Local Const $GWL_STYLE = -16 Local $hWnd = GUICtrlGetHandle($CtrlId) If $hWnd = 0 Then Return SetError(1, 0, 0) ; set SS_BITMAP style to control Local $oldStyle = DllCall("user32.dll", "long", "GetWindowLong", "hwnd", $hWnd, "int", $GWL_STYLE) If @error Then Return SetError(2, 0, 0) DllCall("user32.dll", "long", "SetWindowLong", "hwnd", $hWnd, "int", $GWL_STYLE, "long", BitOR($oldStyle[0], $SS_BITMAP)) If @error Then Return SetError(3, 0, 0) Local $oldBmp = DllCall("user32.dll", "hwnd", "SendMessage", "hwnd", $hWnd, "int", $STM_SETIMAGE, "int", $IMAGE_BITMAP, "int", $hBitmap) If @error Then Return SetError(4, 0, 0) If $oldBmp[0] <> 0 Then _WinAPI_DeleteObject($oldBmp[0]) Return 1 EndFunc Func _WinGetClientPos_Ex($i_tip_Hwnd, $i_tip_ConsiderMenu = False) If Not WinExists($i_tip_Hwnd) Or Not IsHWnd($i_tip_Hwnd) Then Return SetError(1,0,-1) Local $i_tip_WinPos, $i_tip_ClientSize, $i_tip_BorderThickness, $i_tip_aRet $i_tip_WinPos = WinGetPos($i_tip_Hwnd) $i_tip_ClientSize = _WinGetClientSize_Ex($i_tip_Hwnd) $i_tip_BorderThickness = ($i_tip_WinPos[2] - $i_tip_ClientSize[0])/2 Dim $i_tip_aRet[4] = [$i_tip_WinPos[0] + $i_tip_BorderThickness, $i_tip_WinPos[1] + ($i_tip_WinPos[3] - $i_tip_ClientSize[1]) - $i_tip_BorderThickness, $i_tip_ClientSize[0], $i_tip_ClientSize[1]] If $i_tip_ConsiderMenu = True And $i_tip_ClientSize[2] > 0 Then $i_tip_aRet[1] -= $i_tip_ClientSize[2] $i_tip_aRet[3] = $i_tip_ClientSize[3] EndIf Return $i_tip_aRet EndFunc ;==>_WinGetClientPos_Ex Func _WinGetClientSize_Ex($i_tip_Hwnd) If Not WinExists($i_tip_Hwnd) Or Not IsHWnd($i_tip_Hwnd) Then Return SetError(1,0,-1) Local $i_tip_MenuExists, $i_tip_MenuExists, $i_tip_aRet $i_tip_MenuExists = DllCall("User32.dll", "handle", "GetMenu", "hwnd", $i_tip_Hwnd) ; We are checking if parent gui has a menu. If @error Then $i_tip_MenuExists = 0 Else $i_tip_MenuExists = $i_tip_MenuExists[0] If $i_tip_MenuExists > 0 Then $i_tip_MenuExists = 20 Else $i_tip_MenuExists = 0 EndIf EndIf $i_tip_aRet = WinGetClientSize($i_tip_Hwnd) If IsArray($i_tip_aRet) = 0 Then Return SetError(2,0,-1) Else ReDim $i_tip_aRet[4] $i_tip_aRet[2] = $i_tip_MenuExists $i_tip_aRet[3] = $i_tip_aRet[1] + $i_tip_aRet[2] Return $i_tip_aRet EndIf EndFunc ;==>_WinGetClientSize_Ex If you can point me to right direction I'd be very glad. SincerelyTip Edited October 14, 2011 by tip [center]MsgBox_Tipped: Eye candy msgboxes/inputboxes/loginboxes. | CreateBlankBox: Semi-transparent layers with borders and rounded corners.[/center] Link to comment Share on other sites More sharing options...
UEZ Posted October 10, 2011 Share Posted October 10, 2011 (edited) Try this one: expandcollapse popup#include <ScreenCapture.au3> #include <GUIConstantsEx.au3> Opt("MustDeclareVars", 1) Global Const $IMAGE_BITMAP = 0 Global Const $STM_SETIMAGE = 0x0172 _GDIPlus_Startup() Global Const $hGUI = GUICreate("Blur Image and send to Pic Control", 285, 402) Global Const $idPic = GUICtrlCreatePic("", 28, 40, 228, 322) GUISetState() Global Const $pid = Run("calc.exe") ProcessWait($pid) Global $hHBITMAP = _ScreenCapture_CaptureWnd("", WinGetHandle("[CLASS:CalcFrame]")) ;capture screen Sleep(500) ProcessClose($pid) Global $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hHBITMAP) ;convert to GDI+ bitmap _WinAPI_DeleteObject($hHBITMAP) ;delete image object because not needed anymore Global Const $hBitmap_Blur = _Blur($hBitmap, 228, 322) ;blur GDI+ image _GDIPlus_BitmapDispose($hBitmap) ;dispose bitmap because not needed anymore $hHBITMAP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_Blur) ;convert GDI+ bitmap to WinAPI bitmap (reuse of same variable) _GDIPlus_BitmapDispose($hBitmap_Blur) ;dispose bitmap because not needed anymore _WinAPI_DeleteObject(GUICtrlSendMsg($idPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBITMAP)) ;send bitmap to picture control Global $msg Do $msg = GUIGetMsg() Until $msg = $GUI_EVENT_CLOSE _WinAPI_DeleteObject($hHBITMAP) _GDIPlus_Shutdown() GUIDelete($hGUI) Exit Func _Blur($hBitmap, $iW, $iH, $fScale = 0.666666, $qual = 6); by eukalyptus Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND(_WinAPI_GetDesktopWindow()) Local $hBmpSmall = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics) Local $hGfxSmall = _GDIPlus_ImageGetGraphicsContext($hBmpSmall) DllCall($ghGDIPDll, "uint", "GdipSetPixelOffsetMode", "hwnd", $hGfxSmall, "int", 2) Local $hBmpBig = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics) Local $hGfxBig = _GDIPlus_ImageGetGraphicsContext($hBmpBig) DllCall($ghGDIPDll, "uint", "GdipSetPixelOffsetMode", "hwnd", $hGfxBig, "int", 2) DllCall($ghGDIPDll, "uint", "GdipScaleWorldTransform", "hwnd", $hGfxSmall, "float", $fScale, "float", $fScale, "int", 0) DllCall($ghGDIPDll, "uint", "GdipSetInterpolationMode", "hwnd", $hGfxSmall, "int", $qual) DllCall($ghGDIPDll, "uint", "GdipScaleWorldTransform", "hwnd", $hGfxBig, "float", 1 / $fScale, "float", 1 / $fScale, "int", 0) DllCall($ghGDIPDll, "uint", "GdipSetInterpolationMode", "hwnd", $hGfxBig, "int", $qual) _GDIPlus_GraphicsDrawImageRect($hGfxSmall, $hBitmap, 0, 0, $iW, $iH) _GDIPlus_GraphicsDrawImageRect($hGfxBig, $hBmpSmall, 0, 0, $iW, $iH) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_BitmapDispose($hBmpSmall) _GDIPlus_GraphicsDispose($hGfxSmall) _GDIPlus_GraphicsDispose($hGfxBig) Return $hBmpBig EndFunc ;==>_Blur Br, UEZ Edited October 10, 2011 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
tip Posted October 10, 2011 Author Share Posted October 10, 2011 UEZ, thanks for the quick reply. I had used your function but the blur effect is a bit distorted in comparison to Siao's. (I get that you didn't read the whole post ) That's why I've tried to combine your code and his. Can you look at the code in the first post and help me to figure out what is wrong [center]MsgBox_Tipped: Eye candy msgboxes/inputboxes/loginboxes. | CreateBlankBox: Semi-transparent layers with borders and rounded corners.[/center] Link to comment Share on other sites More sharing options...
UEZ Posted October 10, 2011 Share Posted October 10, 2011 (edited) Just play with the $fScale value Br, UEZ Edited October 10, 2011 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!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
tip Posted November 5, 2011 Author Share Posted November 5, 2011 Thank you very much UEZ. Finally I've figured out how to make blur effect more like gaussian blur. "GdipSetSmoothingMode" dllcall is what I needed. Here is the code. Func _GDIPlus_ImageBlur($hBitmap, $iStrenght = 3, $i_WinAPIBMP = False) If $iStrenght <= 1 Then $iStrenght = 1.01 $iStrenght = 1/$iStrenght Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND(_WinAPI_GetDesktopWindow()) $hBitmapWidth = _GDIPlus_ImageGetWidth($hBitmap) $hBitmapHeight = _GDIPlus_ImageGetHeight($hBitmap) Local $hBmpSmall = _GDIPlus_BitmapCreateFromGraphics($hBitmapWidth, $hBitmapHeight, $hGraphics) Local $hGfxSmall = _GDIPlus_ImageGetGraphicsContext($hBmpSmall) DllCall($ghGDIPDll, "uint", "GdipSetPixelOffsetMode", "hwnd", $hGfxSmall, "int", 2) Local $hBmpBig = _GDIPlus_BitmapCreateFromGraphics($hBitmapWidth, $hBitmapHeight, $hGraphics) Local $hGfxBig = _GDIPlus_ImageGetGraphicsContext($hBmpBig) DllCall($ghGDIPDll, "uint", "GdipSetSmoothingMode", "hwnd", $hGfxBig, "int", 7) DllCall($ghGDIPDll, "uint", "GdipSetSmoothingMode", "hwnd", $hGfxSmall, "int", 7) DllCall($ghGDIPDll, "uint", "GdipSetPixelOffsetMode", "hwnd", $hGfxBig, "int", 2) DllCall($ghGDIPDll, "uint", "GdipScaleWorldTransform", "hwnd", $hGfxSmall, "float", $iStrenght, "float", $iStrenght, "int", 0) DllCall($ghGDIPDll, "uint", "GdipSetInterpolationMode", "hwnd", $hGfxSmall, "int", 7) DllCall($ghGDIPDll, "uint", "GdipScaleWorldTransform", "hwnd", $hGfxBig, "float", 1 / $iStrenght, "float", 1 / $iStrenght, "int", 0) DllCall($ghGDIPDll, "uint", "GdipSetInterpolationMode", "hwnd", $hGfxBig, "int", 7) _GDIPlus_GraphicsDrawImageRect($hGfxSmall, $hBitmap, 0, 0, $hBitmapWidth, $hBitmapHeight) _GDIPlus_GraphicsDrawImageRect($hGfxBig, $hBmpSmall, 0, 0, $hBitmapWidth, $hBitmapHeight) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_BitmapDispose($hBmpSmall) _GDIPlus_GraphicsDispose($hGfxSmall) _GDIPlus_GraphicsDispose($hGfxBig) If $i_WinAPIBMP = True Then Local $hHBITMAP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBmpBig) ;convert GDI+ bitmap to WinAPI hbitmap _GDIPlus_BitmapDispose($hBmpBig) Return $hHBITMAP Else Return $hBmpBig EndIf EndFunc ;==>_GDIPlus_ImageBlur Thanks again. Both UEZ and Siao... Regards, Tip [center]MsgBox_Tipped: Eye candy msgboxes/inputboxes/loginboxes. | CreateBlankBox: Semi-transparent layers with borders and rounded corners.[/center] Link to comment Share on other sites More sharing options...
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