pixartist Posted January 4, 2008 Share Posted January 4, 2008 (edited) ok first, here is my script : expandcollapse popup#include <GUIConstants.au3> HotKeySet("{F10}", "blur") Func blur() $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", "") $memory_dc = DllCall("gdi32.dll", "hwnd", "CreateCompatibleDC", "hwnd", $dc[0]) $memory_bm = DllCall("gdi32.dll", "hwnd", "CreateCompatibleBitmap", "ptr", $dc[0], "int", @DesktopWidth, "int", @DesktopHeight) DllCall("gdi32.dll", "hwnd", "SelectObject", "hwnd", $memory_dc[0], "hwnd", $memory_bm[0]) DllCall("gdi32.dll", "int", "BitBlt", "hwnd", $memory_dc[0], "int", 0, "int", 0, "int", @DesktopWidth, "int", @DesktopHeight, "hwnd", $dc[0], "int", 0, "int", 0, "int", 0xCC0020) Dim $x, $y, $cc, $t, $b, $l, $r for $x = 1 to @DesktopWidth-1 for $y = 1 to @DesktopHeight-1 #cs $cc = PixelGetColor($x, $y ) $t = PixelGetColor($x, $y -1) $b = PixelGetColor($x, $y +1) $l = PixelGetColor($x-1, $y ) $r = PixelGetColor($x+1, $y ) #ce $cc = DllCall("gdi32.dll", "long", "GetPixel", "long", $memory_dc[0], "long", $x, "long", $y) $t = DllCall("gdi32.dll", "long", "GetPixel", "long", $memory_dc[0], "long", $x, "long", $y - 1) $b = DllCall("gdi32.dll", "long", "GetPixel", "long", $memory_dc[0], "long", $x, "long", $y + 1) $l = DllCall("gdi32.dll", "long", "GetPixel", "long", $memory_dc[0], "long", $x - 1, "long", $y) $r = DllCall("gdi32.dll", "long", "GetPixel", "long", $memory_dc[0], "long", $x + 1, "long", $y) $rv = Floor(BitShift(BitAND(0xFF0000, $cc[0]), 16) / 5 + BitShift(BitAND(0xFF0000, $l[0]), 16) / 5 + BitShift(BitAND(0xFF0000, $r[0]), 16) / 5 + BitShift(BitAND(0xFF0000, $t[0]), 16) / 5 + BitShift(BitAND(0xFF0000, $b[0]), 16) / 5) ;MsgBox(0,"",$r[0]1&"-"&$r[0]2&"-"&$r[0]3&"-"&$r[0]4&"-"&$r[0]5&"-"&$r[0]v) $gv = Floor((BitShift(BitAND(0x00ff00, $cc[0]), 8) / 5 + BitShift(BitAND(0x00ff00, $l[0]), 8) / 5 + BitShift(BitAND(0x00ff00, $r[0]), 8) / 5 + BitShift(BitAND(0x00ff00, $t[0]), 8) / 5 + BitShift(BitAND(0x00ff00, $b[0]), 8) / 5)) $bv = Floor((BitAND(0xFF, $cc[0]) / 5 + BitAND(0xFF, $l[0]) / 5 + BitAND(0xFF, $r[0]) / 5 + BitAND(0xFF, $t[0]) / 5 + BitAND(0xFF, $b[0]) / 5)) DllCall("gdi32.dll", "long", "SetPixel", "long", $dc[0], "long", $x, "long", $y, "long", "0x" & Hex($rv, 2) & Hex($gv, 2) & Hex($bv, 2)) ;MsgBox(0,"","0x"&hex($rv,2)&hex($gv,2)&hex($bv,2)) Next Next EndFunc While 1 Sleep(1) WEnd aso you see, i capture the screen and get the pixels from the dc in the memory, and i also use bitshift for the color-modification. how can this take like 5 minutes to blur my screen? how can i do it in < 500ms ^^ ? edit: ok it's like 10 million dllcalls, but how should that be possible without calling dll's in the loop ? edit2: if there was just a way to work with pixeldata in hbitmaps directly Edited January 4, 2008 by pixartist Link to comment Share on other sites More sharing options...
James Posted January 4, 2008 Share Posted January 4, 2008 I neatend up your code but couldn't speed it up. If you are not creating a GUI you don't need GUIConstants.au3 HotKeySet("{F10}", "blur") While 1 Sleep(100) WEnd Func blur() ConsoleWrite("Going to blur!" & @CRLF) $dc = DllCall("user32.dll", "int", "GetDC", "hwnd", "") $memory_dc = DllCall("gdi32.dll", "hwnd", "CreateCompatibleDC", "hwnd", $dc[0]) $memory_bm = DllCall("gdi32.dll", "hwnd", "CreateCompatibleBitmap", "ptr", $dc[0], "int", @DesktopWidth, "int", @DesktopHeight) DllCall("gdi32.dll", "hwnd", "SelectObject", "hwnd", $memory_dc[0], "hwnd", $memory_bm[0]) DllCall("gdi32.dll", "int", "BitBlt", "hwnd", $memory_dc[0], "int", 0, "int", 0, "int", @DesktopWidth, "int", @DesktopHeight, "hwnd", $dc[0], "int", 0, "int", 0, "int", 0xCC0020) Dim $x, $y, $cc, $t, $b, $l, $r For $x = 1 To @DesktopWidth - 1 For $y = 1 To @DesktopHeight - 1 $cc = DllCall("gdi32.dll", "long", "GetPixel", "long", $memory_dc[0], "long", $x, "long", $y) $t = DllCall("gdi32.dll", "long", "GetPixel", "long", $memory_dc[0], "long", $x, "long", $y - 1) $b = DllCall("gdi32.dll", "long", "GetPixel", "long", $memory_dc[0], "long", $x, "long", $y + 1) $l = DllCall("gdi32.dll", "long", "GetPixel", "long", $memory_dc[0], "long", $x - 1, "long", $y) $r = DllCall("gdi32.dll", "long", "GetPixel", "long", $memory_dc[0], "long", $x + 1, "long", $y) $rv = Floor(BitShift(BitAND(0xFF0000, $cc[0]), 16) / 5 + BitShift(BitAND(0xFF0000, $l[0]), 16) / 5 + BitShift(BitAND(0xFF0000, $r[0]), 16) / 5 + BitShift(BitAND(0xFF0000, $t[0]), 16) / 5 + BitShift(BitAND(0xFF0000, $b[0]), 16) / 5) $gv = Floor((BitShift(BitAND(0x00ff00, $cc[0]), 8) / 5 + BitShift(BitAND(0x00ff00, $l[0]), 8) / 5 + BitShift(BitAND(0x00ff00, $r[0]), 8) / 5 + BitShift(BitAND(0x00ff00, $t[0]), 8) / 5 + BitShift(BitAND(0x00ff00, $b[0]), 8) / 5)) $bv = Floor((BitAND(0xFF, $cc[0]) / 5 + BitAND(0xFF, $l[0]) / 5 + BitAND(0xFF, $r[0]) / 5 + BitAND(0xFF, $t[0]) / 5 + BitAND(0xFF, $b[0]) / 5)) DllCall("gdi32.dll", "long", "SetPixel", "long", $dc[0], "long", $x, "long", $y, "long", "0x" & Hex($rv, 2) & Hex($gv, 2) & Hex($bv, 2)) Next Next EndFunc ;==>blur Blog - Seriously epic web hosting - Twitter - GitHub - Cachet HQ Link to comment Share on other sites More sharing options...
RobertKipling Posted January 4, 2008 Share Posted January 4, 2008 Darn, if that worked I would have used it too! So this is why Windows Vista is so slow... it takes over a minute to fully "blur" my screen. Clever coding, though! Link to comment Share on other sites More sharing options...
weaponx Posted January 4, 2008 Share Posted January 4, 2008 For every pixel on your screen it collects 4 surrounding pixels. On my 24 inch monitor at 1920 x 1200 (2,304,000 pixels) it is running the GetPixel call 11,520,000 times. Link to comment Share on other sites More sharing options...
jpam Posted January 4, 2008 Share Posted January 4, 2008 384 ms on my 1024x768 screen Link to comment Share on other sites More sharing options...
Bert Posted January 4, 2008 Share Posted January 4, 2008 Would it be worth to get every other pixel, or every 3rd to speed it up? If you are bluring, then the pixel next to it isn't that important. Your goal is distortation, not sharp edges. The Vollatran project  My blog: http://www.vollysinterestingshit.com/ Link to comment Share on other sites More sharing options...
weaponx Posted January 4, 2008 Share Posted January 4, 2008 (edited) Would it be worth to get every other pixel, or every 3rd to speed it up? If you are bluring, then the pixel next to it isn't that important. Your goal is distortation, not sharp edges.I tried this by adding Step 2 to the For loops, still slow and created more of a "lattice". Edited January 4, 2008 by weaponx Link to comment Share on other sites More sharing options...
weaponx Posted January 4, 2008 Share Posted January 4, 2008 (edited) I would think you could use the integrated GDI functions in 3.2.10.0. Capture the screenshot to an object and then run the blur algorithm on it, this way you aren't getting each pixel individually.EDIT: I found a link to a C++ example of this but my eyes went crossed.http://www.codeproject.com/KB/GDI-plus/csh...aspx?print=true Edited January 4, 2008 by weaponx Link to comment Share on other sites More sharing options...
cppman Posted January 4, 2008 Share Posted January 4, 2008 Darn, if that worked I would have used it too! So this is why Windows Vista is so slow... it takes over a minute to fully "blur" my screen. Clever coding, though!That isn't how Vista works. Vista uses Pixel Shaders wich is dedicated hardware for providing the effects you are trying to do. Miva OS Project Link to comment Share on other sites More sharing options...
Siao Posted January 5, 2008 Share Posted January 5, 2008 (edited) IMO no implementation of any gfx transform algo using only native AutoIt commands will be fast enough, especially if we are talking large resolutions. At least that's what my common sense tells me. Scripting languages are meant for other tasks. So you're better off utilizing functions from some dlls. Easy way is to use screen bitmap resizing with GDI+ which has various antialiasing settings. You can play around with SetInterpolationMode, SetPixelOffsetMode etc... For me HighQualityBilinear seems to provide the nicest blurs, especially when stretching alot. expandcollapse popup#include <GUIConstants.au3> #Include <ScreenCapture.au3> #include <GDIPlus.au3> $hGUI = GUICreate("Blurp", 200,120) GUICtrlCreateLabel("InterpolationMode", 20, 20, 100, 20) GUICtrlCreateLabel("Stretch ratio", 20, 50, 100, 20) $cInputIM = GUICtrlCreateInput("6", 120, 15, 50, 20) GUICtrlSetTip(-1, "Possible values" & @CRLF & "0 - 7") $cInputSR = GUICtrlCreateInput("1.25", 120, 45, 50, 20) GUICtrlSetTip(-1, "Possible values" & @CRLF & "1.0 - @DesktopHeight.0") $cBtnBlur = GUICtrlCreateButton("Blur", 20, 80, 80, 20) $cBtnClear = GUICtrlCreateButton("Clear", 100, 80, 80, 20) GUISetState() _GDIPlus_Startup() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE _GDIPlus_Shutdown() Exit Case $cBtnBlur _ScreenBlur(GUICtrlRead($cInputSR), GUICtrlRead($cInputIM)) Case $cBtnClear _ScreenClear() EndSwitch WEnd Func _ScreenClear() _WinAPI_RedrawWindow(_WinAPI_GetDesktopWindow(), 0, 0, $RDW_INVALIDATE+$RDW_UPDATENOW+$RDW_ALLCHILDREN) EndFunc Func _ScreenBlur($nRatio, $iInterMode, $iSmoothMode=0, $iPixOffsetMode = 2) $hBMP = _ScreenCapture_Capture("", 0,0,-1,-1, False) $hImg = _GDIPlus_BitmapCreateFromHBITMAP($hBMP) $hScreenDC = _WinAPI_GetDC(0) $hScreenGraph = _GDIPlus_GraphicsCreateFromHDC($hScreenDC) $hImg2 = _GDIPlus_BitmapCloneArea($hImg, 0, 0, @DesktopWidth/$nRatio, @DesktopHeight/$nRatio) $hMemGraph = _GDIPlus_ImageGetGraphicsContext($hImg2) ;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 $a = DllCall("gdiplus.dll", "int", "GdipSetInterpolationMode", "hwnd", $hMemGraph, "int", $iInterMode) $a = DllCall("gdiplus.dll", "int", "GdipSetInterpolationMode", "hwnd", $hScreenGraph, "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 $a = DllCall("gdiplus.dll", "int", "GdipSetPixelOffsetMode", "hwnd", $hMemGraph, "int", $iPixOffsetMode) $a = DllCall("gdiplus.dll", "int", "GdipSetPixelOffsetMode", "hwnd", $hScreenGraph, "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 $a = DllCall("gdiplus.dll", "int", "GdipSetSmoothingMode", "hwnd", $hMemGraph, "int", $iSmoothMode) $a = DllCall("gdiplus.dll", "int", "GdipSetSmoothingMode", "hwnd", $hScreenGraph, "int", $iSmoothMode) _GDIPlus_GraphicsDrawImageRectRect($hMemGraph, $hImg, 0, 0, @DesktopWidth, @DesktopHeight, 0, 0, @DesktopWidth/$nRatio, @DesktopHeight/$nRatio) _GDIPlus_GraphicsDrawImageRectRect($hScreenGraph, $hImg2, 0, 0, @DesktopWidth/$nRatio, @DesktopHeight/$nRatio, 0, 0, @DesktopWidth, @DesktopHeight) _WinAPI_DeleteObject($hBMP) _GDIPlus_ImageDispose($hImg) _GDIPlus_ImageDispose($hImg2) _GDIPlus_GraphicsDispose($hMemGraph) _GDIPlus_GraphicsDispose($hScreenGraph) _WinAPI_ReleaseDC(0, $hScreenDC) EndFunc Edit: updated example - some tinkering with and documentation of modes. Edited January 5, 2008 by Siao "be smart, drink your wine" Link to comment Share on other sites More sharing options...
pixartist Posted January 6, 2008 Author Share Posted January 6, 2008 IMO no implementation of any gfx transform algo using only native AutoIt commands will be fast enough, especially if we are talking large resolutions. At least that's what my common sense tells me. Scripting languages are meant for other tasks. So you're better off utilizing functions from some dlls. Easy way is to use screen bitmap resizing with GDI+ which has various antialiasing settings. You can play around with SetInterpolationMode, SetPixelOffsetMode etc... For me HighQualityBilinear seems to provide the nicest blurs, especially when stretching alot. expandcollapse popup#include <GUIConstants.au3> #Include <ScreenCapture.au3> #include <GDIPlus.au3> $hGUI = GUICreate("Blurp", 200,120) GUICtrlCreateLabel("InterpolationMode", 20, 20, 100, 20) GUICtrlCreateLabel("Stretch ratio", 20, 50, 100, 20) $cInputIM = GUICtrlCreateInput("6", 120, 15, 50, 20) GUICtrlSetTip(-1, "Possible values" & @CRLF & "0 - 7") $cInputSR = GUICtrlCreateInput("1.25", 120, 45, 50, 20) GUICtrlSetTip(-1, "Possible values" & @CRLF & "1.0 - @DesktopHeight.0") $cBtnBlur = GUICtrlCreateButton("Blur", 20, 80, 80, 20) $cBtnClear = GUICtrlCreateButton("Clear", 100, 80, 80, 20) GUISetState() _GDIPlus_Startup() While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE _GDIPlus_Shutdown() Exit Case $cBtnBlur _ScreenBlur(GUICtrlRead($cInputSR), GUICtrlRead($cInputIM)) Case $cBtnClear _ScreenClear() EndSwitch WEnd Func _ScreenClear() _WinAPI_RedrawWindow(_WinAPI_GetDesktopWindow(), 0, 0, $RDW_INVALIDATE+$RDW_UPDATENOW+$RDW_ALLCHILDREN) EndFunc Func _ScreenBlur($nRatio, $iInterMode, $iSmoothMode=0, $iPixOffsetMode = 2) $hBMP = _ScreenCapture_Capture("", 0,0,-1,-1, False) $hImg = _GDIPlus_BitmapCreateFromHBITMAP($hBMP) $hScreenDC = _WinAPI_GetDC(0) $hScreenGraph = _GDIPlus_GraphicsCreateFromHDC($hScreenDC) $hImg2 = _GDIPlus_BitmapCloneArea($hImg, 0, 0, @DesktopWidth/$nRatio, @DesktopHeight/$nRatio) $hMemGraph = _GDIPlus_ImageGetGraphicsContext($hImg2) ;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 $a = DllCall("gdiplus.dll", "int", "GdipSetInterpolationMode", "hwnd", $hMemGraph, "int", $iInterMode) $a = DllCall("gdiplus.dll", "int", "GdipSetInterpolationMode", "hwnd", $hScreenGraph, "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 $a = DllCall("gdiplus.dll", "int", "GdipSetPixelOffsetMode", "hwnd", $hMemGraph, "int", $iPixOffsetMode) $a = DllCall("gdiplus.dll", "int", "GdipSetPixelOffsetMode", "hwnd", $hScreenGraph, "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 $a = DllCall("gdiplus.dll", "int", "GdipSetSmoothingMode", "hwnd", $hMemGraph, "int", $iSmoothMode) $a = DllCall("gdiplus.dll", "int", "GdipSetSmoothingMode", "hwnd", $hScreenGraph, "int", $iSmoothMode) _GDIPlus_GraphicsDrawImageRectRect($hMemGraph, $hImg, 0, 0, @DesktopWidth, @DesktopHeight, 0, 0, @DesktopWidth/$nRatio, @DesktopHeight/$nRatio) _GDIPlus_GraphicsDrawImageRectRect($hScreenGraph, $hImg2, 0, 0, @DesktopWidth/$nRatio, @DesktopHeight/$nRatio, 0, 0, @DesktopWidth, @DesktopHeight) _WinAPI_DeleteObject($hBMP) _GDIPlus_ImageDispose($hImg) _GDIPlus_ImageDispose($hImg2) _GDIPlus_GraphicsDispose($hMemGraph) _GDIPlus_GraphicsDispose($hScreenGraph) _WinAPI_ReleaseDC(0, $hScreenDC) EndFunc Edit: updated example - some tinkering with and documentation of modes.wow thats actually pretty good! an fast! thank you Link to comment Share on other sites More sharing options...
dandymcgee Posted January 6, 2008 Share Posted January 6, 2008 Hehe, that's a neat program. - Dan [Website] Link to comment Share on other sites More sharing options...
torun Posted February 1, 2008 Share Posted February 1, 2008 I tried to run the example, but gdiplus.au3 gives errors. A Messagebox appears with: Fatal error: AVector: []: Out of bounds After closing this message box I get the Blurp window, but when I click [blur] I get the same fatal error a few times and the lower window in SCITE shows: C:\Program Files\AutoIt3\Include\GDIPlus.au3 (415) : ==> Subscript used with non-Array variable.: Return SetError($aResult[0], 0, $aResult[7]) Return SetError($aResult^ ERROR I am using autoit v3.2.10.0 and WINNT4 (is this the reason?). Link to comment Share on other sites More sharing options...
weaponx Posted February 1, 2008 Share Posted February 1, 2008 I tried to run the example, but gdiplus.au3 gives errors. A Messagebox appears with: Fatal error: AVector: []: Out of bounds After closing this message box I get the Blurp window, but when I click [blur] I get the same fatal error a few times and the lower window in SCITE shows: C:\Program Files\AutoIt3\Include\GDIPlus.au3 (415) : ==> Subscript used with non-Array variable.: Return SetError($aResult[0], 0, $aResult[7]) Return SetError($aResult^ ERROR I am using autoit v3.2.10.0 and WINNT4 (is this the reason?). Windows NT does not come with GDI+ installed. Link to comment Share on other sites More sharing options...
Siao Posted February 1, 2008 Share Posted February 1, 2008 (edited) See http://msdn2.microsoft.com/en-us/library/m...798(VS.85).aspx Edited February 1, 2008 by Siao "be smart, drink your wine" Link to comment Share on other sites More sharing options...
strate Posted January 2, 2009 Share Posted January 2, 2009 Is it possible to dump the blurred image to a file, so that you never see the bluring until you open the file? INI TreeViewA bus station is where a bus stops, a train station is where a train stops. Onmy desk I have a work station... 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