Jump to content
Sign in to follow this  
Yashied

_GDIPlus_BitmapCreateBlurBitmap()

Recommended Posts

Yashied

This function allows you to blur the specified GDI+ bitmap with different force of blur (see screenshots, 1 - source image, 2 - blurring image with L=5, 3 - blurring image with L=10). The source bitmap may be of any color depth, the output bitmap is always 32 bits-per-pixel with alpha channel. The function creates a few parallel threads (up to 8), that significantly reduces the time consumption. It's worth noting that the blurring is performed for all channels, including the alpha channel.

post_img_097.pngpost_img_098.pngpost_img_099.png

The following shows the basic algorithm for a simple blur of bitmap written in AutoIt. Unfortunately, it is not possible to solve using AutoIt because the processing of even a small picture may require too much time. For example, blurring image 100x100 can last a few seconds. To solve this problem, I compiled the time-consuming part of code (main loop) to machine code. This solved the problem of the time consumption but I wanted to get better results, especially for large images (more than 1000x1000) and large blur radius (10+). Then I divided the source image into several parts and started the blurring of each part in a separate thread. Now it's become quite good. See below for a complete example written for Autoit 3.3.12.0.

; Scans the source bitmap pixel by pixel
For $Yi = 0 To $H - 1
    For $Xi = To $W - 1
        $A = 0
        $R = 0
        $G = 0
        $B = 0
        $Count = 0
        ; Calculates the average value for each color channel of source bitmap (including alpha chennel)
        For $Yj = $Yi - $L To $Yi + $L
            For $Xj = $Xi - $L To $Xi + $L
                If ($Xj >= 0) And ($Xj < $W) And ($Yj >= 0) And ($Yj < $H) Then
                    $ARGB = DllStructCreate('BYTE B;BYTE G;BYTE R;BYTE A', $pBitsSrc + ($Xj + $Yj * $W) * 4)
                    $A += $ARGB.A
                    $R += $ARGB.R
                    $G += $ARGB.G
                    $B += $ARGB.B
                    $Count += 1
                EndIf
            Next
        Next
        ; Writes the calculated color to the corresponding pixel of destination bitmap
        $ARGB = DllStructCreate('BYTE B;BYTE G;BYTE R;BYTE A', $pBitsDst + ($Xj + $Yj * $W) * 4)
        $ARGB.A = $A / $Count
        $ARGB.R = $R / $Count
        $ARGB.G = $G / $Count
        $ARGB.B = $B / $Count
    Next
Next

post_img_100.png

#Include <GDIPlus.au3>

If StringRegExpReplace(@AutoItVersion, '(?<!\d)(\d)(?!\d)', '0\1') < '03.03.12.00' Then
    MsgBox(16, 'Error', 'Require AutoIt 3.3.12.0 or later.')
EndIf

$sFile = @ScriptDir & '\Birds.png'

_GDIPlus_Startup()
$hBitmap = _GDIPlus_BitmapCreateFromFile($sFile)
$hBlur = _GDIPlus_BitmapCreateBlurBitmap($hBitmap, 5, 1)
_GDIPlus_ImageSaveToFile($hBlur, StringRegExpReplace($sFile, '(\.[^\.]+)', '_Blur\1'))
_GDIPlus_BitmapDispose($hBlur)
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_Shutdown()

Func _GDIPlus_BitmapCreateBlurBitmap($hBitmap, $iRadius, $fAccurate = False)

    Local $tData[2], $hThread, $iThread, $tParams, $bProc, $tProc, $pProc, $aSize, $aHeight, $iLength, $hResult, $aResult

    $aSize = DllCall($__g_hGDIPDll, 'uint', 'GdipGetImageDimension', 'handle', $hBitmap, 'float*', 0, 'float*', 0)
    If (@Error) Or ($aSize[0]) Then
        Return 0
    EndIf
    For $i = 2 To 3
        If $iRadius > $aSize[$i] Then
            $iRadius = $aSize[$i]
        EndIf
    Next
    If $iRadius < 1 Then
        Return 0
    EndIf
    $hResult  = _GDIPlus_BitmapCreateFromScan0($aSize[2], $aSize[3], $GDIP_PXF32ARGB)
    $tData[0] = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $aSize[2], $aSize[3], $GDIP_ILMREAD,  $GDIP_PXF32ARGB)
    $tData[1] = _GDIPlus_BitmapLockBits($hResult, 0, 0, $aSize[2], $aSize[3], $GDIP_ILMWRITE, $GDIP_PXF32ARGB)
    If @AutoItX64 Then
        $bProc = Binary('0x48894C24085541574156415548C7C00A0000004883EC0848C704240000000048FFC875EF4883EC28488BAC24A000000048837D000074054831C0EB0748C7C0010000004821C00F855E010000488BAC24A000000048837D080074054831C0EB0748C7C0010000004821C00F8527010000488BAC24A0000000837D180074054831C0EB0748C7C0010000004821C00F85F1000000488BAC24A0000000837D1C0074054831C0EB0748C7C0010000004821C00F85BB000000488BAC24A0000000837D200074054831C0EB0748C7C0010000004821C00F8585000000488BAC24A0000000837D240074054831C0EB0748C7C0010000004821C07553488BAC24A0000000837D280074054831C0EB0748C7C0010000004821C07521488BAC24A0000000837D2C0074054831C0EB0748C7C0010000004821C07502EB0948C7C001000000EB034831C04821C07502EB0948C7C001000000EB034831C04821C07502EB0948C7C001000000EB034831C04821C07502EB0948C7C001000000EB034831C04821C07502EB0948C7C001000000EB034831C04821C07502EB0948C7C001000000EB034831C04821C07502EB0948C7C001000000EB034831C04821C0740B4831C04863C0E946030000488BAC24A00000004863451450584889442428488BAC24A00000004C637D14488BAC24A00000004863451C4901C749FFCF4C3B7C24280F8CFB020000488BAC24A00000004863451050584889442430488BAC24A00000004C637D10488BAC24A0000000486345184901C749FFCF4C3B7C24300F8CB402000048C74424380000000048C74424400000000048C74424480000000048C74424500000000048C7442458000000004C8B7C2428488BAC24A0000000486345284929C74C897C24604C8B7C24604C8B742428488BAC24A0000000486345284901C64D39F70F8F840100004C8B7C2430488BAC24A0000000486345284929C74C897C24684C8B7C24684C8B742430488BAC24A0000000486345284901C64D39F70F8F2B0100004C8B7C24684D21FF7C614C8B7C2468488BAC24A0000000486345204939C77D3A4C8B7C24604D21FF7C1F4C8B7C2460488BAC24A0000000486345244939C77D0948C7C001000000EB034831C04821C0740948C7C001000000EB034831C04821C0740948C7C001000000EB034831C04821C00F8496000000488BAC24A00000004C8B7D004C8B7424684C8B6C2460488BAC24A0000000486345204C0FAFE84D01EE49C1E6024D01F74C897C24704C8B7C2438488B6C2470480FB645034901C74C897C24384C8B7C2440488B6C2470480FB645024901C74C897C24404C8B7C2448488B6C2470480FB645014901C74C897C24484C8B7C2450488B6C2470480FB645004901C74C897C245048FF4424584C8B7C2468488BAC24A00000004863452C4901C74C897C2468E9B3FEFFFF4C8B7C2460488BAC24A00000004863452C4901C74C897C2460E95AFEFFFF488BAC24A00000004C8B7D084C8B7424304C8B6C2428488BAC24A0000000486345204C0FAFE84D01EE49C1E6024D01F74C897C24704C8B7C2438FF7424584C89F859489948F7F94989C74C89F850488B6C2478588845034C8B7C2440FF7424584C89F859489948F7F94989C74C89F850488B6C2478588845024C8B7C2448FF7424584C89F859489948F7F94989C74C89F850488B6C2478588845014C8B7C2450FF7424584C89F859489948F7F94989C74C89F850488B6C24785888450048FF4424300F8123FDFFFF48FF4424280F81DCFCFFFF48C7C0010000004863C0EB034831C04883C478415D415E415F5DC3')
    Else
        $bProc = Binary('0x55535756BA0A00000083EC04C70424000000004A75F38B6C243C837D0000740431C0EB05B80100000021C00F85090100008B6C243C837D0400740431C0EB05B80100000021C00F85DF0000008B6C243C837D1000740431C0EB05B80100000021C00F85B50000008B6C243C837D1400740431C0EB05B80100000021C00F858B0000008B6C243C837D1800740431C0EB05B80100000021C075658B6C243C837D1C00740431C0EB05B80100000021C0753F8B6C243C837D2000740431C0EB05B80100000021C075198B6C243C837D2400740431C0EB05B80100000021C07502EB07B801000000EB0231C021C07502EB07B801000000EB0231C021C07502EB07B801000000EB0231C021C07502EB07B801000000EB0231C021C07502EB07B801000000EB0231C021C07502EB07B801000000EB0231C021C07502EB07B801000000EB0231C021C0740731C0E9400200008B6C243C8B450C8904248B6C243C8B5D0C8B6C243C035D144B3B1C240F8C150200008B6C243C8B4508894424048B6C243C8B5D088B6C243C035D104B3B5C24040F8CE8010000C744240800000000C744240C00000000C744241000000000C744241400000000C7442418000000008B1C248B6C243C2B5D20895C241C8B5C241C8B3C248B6C243C037D2039FB0F8F0D0100008B5C24048B6C243C2B5D20895C24208B5C24208B7C24048B6C243C037D2039FB0F8FD30000008B5C242021DB7C438B5C24208B6C243C3B5D187D298B5C241C21DB7C148B5C241C8B6C243C3B5D1C7D07B801000000EB0231C021C07407B801000000EB0231C021C07407B801000000EB0231C021C0746E8B6C243C8B5D008B7C24208B74241C8B6C243C0FAF751801F7C1E70201FB895C24248B5C24088B6C24240FB6450301C3895C24088B5C240C8B6C24240FB6450201C3895C240C8B5C24108B6C24240FB6450101C3895C24108B5C24148B6C24240FB6450001C3895C2414FF4424188B5C24208B6C243C035D24895C2420E916FFFFFF8B5C241C8B6C243C035D24895C241CE9DDFEFFFF8B6C243C8B5D048B7C24048B34248B6C243C0FAF751801F7C1E70201FB895C24248B5C2408FF74241889D85999F7F989C3538B6C2428588845038B5C240CFF74241889D85999F7F989C3538B6C2428588845028B5C2410FF74241889D85999F7F989C3538B6C2428588845018B5C2414FF74241889D85999F7F989C3538B6C242858884500FF4424040F81FFFDFFFFFF04240F81D3FDFFFFB801000000EB0231C083C4285E5F5B5DC20400')
    EndIf
    $iLength = BinaryLen($bProc)
    $pProc = DllCall('kernel32.dll', 'ptr', 'VirtualAlloc', 'ptr', 0, 'ulong_ptr', $iLength, 'dword', 0x1000, 'dword', 0x0040)
    $tProc = DllStructCreate('byte[' & $iLength & ']', $pProc[0])
    DllStructSetData($tProc, 1, $bProc)
    $iThread = 8
    If $iThread > $aSize[3] Then
        $iThread = $aSize[3]
    EndIf
    Dim $aHeight[$iThread]
    Dim $tParams[$iThread]
    Dim $hThread[$iThread]
    If $iThread = 1 Then
        $aHeight[0] = $aSize[3]
    Else
        $aHeight[0] = Floor($aSize[3] / $iThread)
        $aHeight[$iThread - 1] = $aSize[3] - $aHeight[0] * ($iThread - 1)
        For $i = 1 To $iThread - 2
            $aHeight[$i] = $aHeight[0]
        Next
    EndIf
    $iLength = 0
    For $i = 0 To $iThread - 1
        $tParams[$i] = DllStructCreate('ptr;ptr;uint;uint;uint;uint;uint;uint;uint;uint')
        DllStructSetData($tParams[$i], 1, $tData[0].Scan0)
        DllStructSetData($tParams[$i], 2, $tData[1].Scan0)
        DllStructSetData($tParams[$i], 3, 0)
        DllStructSetData($tParams[$i], 4, $iLength)
        DllStructSetData($tParams[$i], 5, $aSize[2])
        DllStructSetData($tParams[$i], 6, $aHeight[$i])
        DllStructSetData($tParams[$i], 7, $aSize[2])
        DllStructSetData($tParams[$i], 8, $aSize[3])
        DllStructSetData($tParams[$i], 9, $iRadius)
        If $fAccurate Then
            DllStructSetData($tParams[$i],10, 1)
        Else
            DllStructSetData($tParams[$i],10, 2)
        EndIf
        $iLength+= $aHeight[$i]
        $aResult = DllCall('kernel32.dll', 'handle', 'CreateThread', 'ptr', 0, 'dword_ptr', 0, 'ptr', $pProc[0], 'struct*', $tParams[$i], 'dword', 0, 'ptr', 0)
        If (Not @Error) And ($aResult[0]) Then
            $hThread[$i] = $aResult[0]
        Else
            $hThread[$i] = 0
        EndIf
    Next
    While 1
        $iLength = 0
        For $i = 0 To $iThread - 1
            If $hThread[$i] Then
                $aResult = DllCall('kernel32.dll', 'bool', 'GetExitCodeThread', 'handle', $hThread[$i], 'dword*', 0)
                If (@Error) Or (Not $aResult[0]) Or ($aResult[2] <> 259) Then
                    DllCall('kernel32.dll', 'bool', 'CloseHandle', 'handle', $hThread[$i])
                    $hThread[$i] = 0
                Else
                    $iLength += 1
                EndIf
            EndIf
        Next
        If Not $iLength Then
            ExitLoop
        EndIf
    WEnd
    $aResult = DllCall('kernel32.dll', 'int', 'VirtualFree', 'ptr', $pProc[0], 'ulong_ptr', 0, 'dword', 0x4000)
    If (@Error) Or (Not $aResult[0]) Then
        ; Nothing
    EndIf
    _GDIPlus_BitmapUnlockBits($hResult, $tData[1])
    _GDIPlus_BitmapUnlockBits($hBitmap, $tData[0])
    Return $hResult
EndFunc   ;==>_GDIPlus_BitmapCreateBlurBitmap

Function + Example

Previous downloads: 17

GDIPlus_BitmapCreateBlurBitmap.zip

Edited by Yashied
  • Like 1

Share this post


Link to post
Share on other sites
UEZ

I compared the speed of following 3 blur functions:

 

#include <Screencapture.au3>

If StringRegExpReplace(@AutoItVersion, '(?<!\d)(\d)(?!\d)', '0\1') < '03.03.12.00' Then
    MsgBox(16, 'Error', 'Require AutoIt 3.3.12.0 or later.')
EndIf

$sFile = @ScriptDir & '\Birds.png'

_GDIPlus_Startup()
$hGDI = _ScreenCapture_Capture("", 1, 1, 1024, 768)
$hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hGDI)
$t = TimerInit()
$hBlur = _GDIPlus_BitmapCreateBlurBitmap($hBitmap, 5, 1)
ConsoleWrite(TimerDiff($t) & @CRLF)
$t = TimerInit()
$hBlur2 = _GDIPlus_BitmapCreateBlurBitmapv10($hBitmap)
ConsoleWrite(TimerDiff($t) & @CRLF)
$t = TimerInit()
_GDIPlus_BitmapCreateBlurBitmapv11($hBitmap, 10)
ConsoleWrite(TimerDiff($t) & @CRLF)

_GDIPlus_ImageSaveToFile($hBlur, StringRegExpReplace($sFile, '(\.[^\.]+)', '_Blur\1'))
_GDIPlus_ImageSaveToFile($hBlur2, StringRegExpReplace($sFile, '(\.[^\.]+)', '_Blur2\1'))
_GDIPlus_ImageSaveToFile($hBitmap, StringRegExpReplace($sFile, '(\.[^\.]+)', '_Blur3\1'))
_GDIPlus_BitmapDispose($hBlur)
_GDIPlus_BitmapDispose($hBlur2)
_GDIPlus_BitmapDispose($hBitmap)
_WinAPI_DeleteObject($hGDI)
_GDIPlus_Shutdown()

Func _GDIPlus_BitmapCreateBlurBitmapv11($hBitmap, $iRadius) ;requires GDIPlus v1.1 available on Vista and higher operating systems
    Local Const $hEffect = _GDIPlus_EffectCreateBlur($iRadius)
    _GDIPlus_BitmapApplyEffect($hBitmap, $hEffect)
     _GDIPlus_EffectDispose($hEffect)
    Return 1
EndFunc

Func _GDIPlus_BitmapCreateBlurBitmapv10($hBitmap, $fScale = 0.2, $iQual = 6); by eukalyptus
    Local Const $iW = _GDIPlus_ImageGetWidth($hBitmap), $iH = _GDIPlus_ImageGetHeight($hBitmap)
    Local Const $hGraphics = _GDIPlus_GraphicsCreateFromHWND(_WinAPI_GetDesktopWindow())
    Local Const $hBmpSmall = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics)
    Local Const $hGfxSmall = _GDIPlus_ImageGetGraphicsContext($hBmpSmall)
    _GDIPlus_GraphicsSetPixelOffsetMode($hGfxSmall, $GDIP_PIXELOFFSETMODE_HIGHQUALITY)
    Local Const $hBmpBig = _GDIPlus_BitmapCreateFromGraphics($iW, $iH, $hGraphics)
    Local Const $hGfxBig = _GDIPlus_ImageGetGraphicsContext($hBmpBig)
    _GDIPlus_GraphicsSetPixelOffsetMode($hGfxBig, $GDIP_PIXELOFFSETMODE_HIGHQUALITY)
    _GDIPlus_GraphicsScaleTransform($hGfxSmall, $fScale, $fScale)
    _GDIPlus_GraphicsSetInterpolationMode($hGfxSmall, $iQual)
    _GDIPlus_GraphicsScaleTransform($hGfxBig, 1 / $fScale, 1 / $fScale)
    _GDIPlus_GraphicsSetInterpolationMode($hGfxBig, $iQual)
    _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

Func _GDIPlus_BitmapCreateBlurBitmap($hBitmap, $iRadius, $fAccurate = False)

    Local $tData[2], $hThread, $iThread, $tParams, $bProc, $tProc, $pProc, $aSize, $aHeight, $iLength, $hResult, $aResult

    $aSize = DllCall($__g_hGDIPDll, 'uint', 'GdipGetImageDimension', 'handle', $hBitmap, 'float*', 0, 'float*', 0)
    If (@Error) Or ($aSize[0]) Then
        Return 0
    EndIf
    For $i = 2 To 3
        If $iRadius > $aSize[$i] Then
            $iRadius = $aSize[$i]
        EndIf
    Next
    If $iRadius < 1 Then
        Return 0
    EndIf
    $hResult  = _GDIPlus_BitmapCreateFromScan0($aSize[2], $aSize[3], $GDIP_PXF32ARGB)
    $tData[0] = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $aSize[2], $aSize[3], $GDIP_ILMREAD,  $GDIP_PXF32ARGB)
    $tData[1] = _GDIPlus_BitmapLockBits($hResult, 0, 0, $aSize[2], $aSize[3], $GDIP_ILMWRITE, $GDIP_PXF32ARGB)
    If @AutoItX64 Then
        $bProc = Binary('0x48894C24085541574156415548C7C00A0000004883EC0848C704240000000048FFC875EF4883EC28488BAC24A000000048837D000074054831C0EB0748C7C0010000004821C00F855E010000488BAC24A000000048837D080074054831C0EB0748C7C0010000004821C00F8527010000488BAC24A0000000837D180074054831C0EB0748C7C0010000004821C00F85F1000000488BAC24A0000000837D1C0074054831C0EB0748C7C0010000004821C00F85BB000000488BAC24A0000000837D200074054831C0EB0748C7C0010000004821C00F8585000000488BAC24A0000000837D240074054831C0EB0748C7C0010000004821C07553488BAC24A0000000837D280074054831C0EB0748C7C0010000004821C07521488BAC24A0000000837D2C0074054831C0EB0748C7C0010000004821C07502EB0948C7C001000000EB034831C04821C07502EB0948C7C001000000EB034831C04821C07502EB0948C7C001000000EB034831C04821C07502EB0948C7C001000000EB034831C04821C07502EB0948C7C001000000EB034831C04821C07502EB0948C7C001000000EB034831C04821C07502EB0948C7C001000000EB034831C04821C0740B4831C04863C0E946030000488BAC24A00000004863451450584889442428488BAC24A00000004C637D14488BAC24A00000004863451C4901C749FFCF4C3B7C24280F8CFB020000488BAC24A00000004863451050584889442430488BAC24A00000004C637D10488BAC24A0000000486345184901C749FFCF4C3B7C24300F8CB402000048C74424380000000048C74424400000000048C74424480000000048C74424500000000048C7442458000000004C8B7C2428488BAC24A0000000486345284929C74C897C24604C8B7C24604C8B742428488BAC24A0000000486345284901C64D39F70F8F840100004C8B7C2430488BAC24A0000000486345284929C74C897C24684C8B7C24684C8B742430488BAC24A0000000486345284901C64D39F70F8F2B0100004C8B7C24684D21FF7C614C8B7C2468488BAC24A0000000486345204939C77D3A4C8B7C24604D21FF7C1F4C8B7C2460488BAC24A0000000486345244939C77D0948C7C001000000EB034831C04821C0740948C7C001000000EB034831C04821C0740948C7C001000000EB034831C04821C00F8496000000488BAC24A00000004C8B7D004C8B7424684C8B6C2460488BAC24A0000000486345204C0FAFE84D01EE49C1E6024D01F74C897C24704C8B7C2438488B6C2470480FB645034901C74C897C24384C8B7C2440488B6C2470480FB645024901C74C897C24404C8B7C2448488B6C2470480FB645014901C74C897C24484C8B7C2450488B6C2470480FB645004901C74C897C245048FF4424584C8B7C2468488BAC24A00000004863452C4901C74C897C2468E9B3FEFFFF4C8B7C2460488BAC24A00000004863452C4901C74C897C2460E95AFEFFFF488BAC24A00000004C8B7D084C8B7424304C8B6C2428488BAC24A0000000486345204C0FAFE84D01EE49C1E6024D01F74C897C24704C8B7C2438FF7424584C89F859489948F7F94989C74C89F850488B6C2478588845034C8B7C2440FF7424584C89F859489948F7F94989C74C89F850488B6C2478588845024C8B7C2448FF7424584C89F859489948F7F94989C74C89F850488B6C2478588845014C8B7C2450FF7424584C89F859489948F7F94989C74C89F850488B6C24785888450048FF4424300F8123FDFFFF48FF4424280F81DCFCFFFF48C7C0010000004863C0EB034831C04883C478415D415E415F5DC3')
    Else
        $bProc = Binary('0x55535756BA0A00000083EC04C70424000000004A75F38B6C243C837D0000740431C0EB05B80100000021C00F85090100008B6C243C837D0400740431C0EB05B80100000021C00F85DF0000008B6C243C837D1000740431C0EB05B80100000021C00F85B50000008B6C243C837D1400740431C0EB05B80100000021C00F858B0000008B6C243C837D1800740431C0EB05B80100000021C075658B6C243C837D1C00740431C0EB05B80100000021C0753F8B6C243C837D2000740431C0EB05B80100000021C075198B6C243C837D2400740431C0EB05B80100000021C07502EB07B801000000EB0231C021C07502EB07B801000000EB0231C021C07502EB07B801000000EB0231C021C07502EB07B801000000EB0231C021C07502EB07B801000000EB0231C021C07502EB07B801000000EB0231C021C07502EB07B801000000EB0231C021C0740731C0E9400200008B6C243C8B450C8904248B6C243C8B5D0C8B6C243C035D144B3B1C240F8C150200008B6C243C8B4508894424048B6C243C8B5D088B6C243C035D104B3B5C24040F8CE8010000C744240800000000C744240C00000000C744241000000000C744241400000000C7442418000000008B1C248B6C243C2B5D20895C241C8B5C241C8B3C248B6C243C037D2039FB0F8F0D0100008B5C24048B6C243C2B5D20895C24208B5C24208B7C24048B6C243C037D2039FB0F8FD30000008B5C242021DB7C438B5C24208B6C243C3B5D187D298B5C241C21DB7C148B5C241C8B6C243C3B5D1C7D07B801000000EB0231C021C07407B801000000EB0231C021C07407B801000000EB0231C021C0746E8B6C243C8B5D008B7C24208B74241C8B6C243C0FAF751801F7C1E70201FB895C24248B5C24088B6C24240FB6450301C3895C24088B5C240C8B6C24240FB6450201C3895C240C8B5C24108B6C24240FB6450101C3895C24108B5C24148B6C24240FB6450001C3895C2414FF4424188B5C24208B6C243C035D24895C2420E916FFFFFF8B5C241C8B6C243C035D24895C241CE9DDFEFFFF8B6C243C8B5D048B7C24048B34248B6C243C0FAF751801F7C1E70201FB895C24248B5C2408FF74241889D85999F7F989C3538B6C2428588845038B5C240CFF74241889D85999F7F989C3538B6C2428588845028B5C2410FF74241889D85999F7F989C3538B6C2428588845018B5C2414FF74241889D85999F7F989C3538B6C242858884500FF4424040F81FFFDFFFFFF04240F81D3FDFFFFB801000000EB0231C083C4285E5F5B5DC20400')
    EndIf
    $iLength = BinaryLen($bProc)
    $pProc = DllCall('kernel32.dll', 'ptr', 'VirtualAlloc', 'ptr', 0, 'ulong_ptr', $iLength, 'dword', 0x1000, 'dword', 0x0040)
    $tProc = DllStructCreate('byte[' & $iLength & ']', $pProc[0])
    DllStructSetData($tProc, 1, $bProc)
    $iThread = 8
    If $iThread > $aSize[3] Then
        $iThread = $aSize[3]
    EndIf
    Dim $aHeight[$iThread]
    Dim $tParams[$iThread]
    Dim $hThread[$iThread]
    If $iThread = 1 Then
        $aHeight[0] = $aSize[3]
    Else
        $aHeight[0] = Floor($aSize[3] / $iThread)
        $aHeight[$iThread - 1] = $aSize[3] - $aHeight[0] * ($iThread - 1)
        For $i = 1 To $iThread - 2
            $aHeight[$i] = $aHeight[0]
        Next
    EndIf
    $iLength = 0
    For $i = 0 To $iThread - 1
        $tParams[$i] = DllStructCreate('ptr;ptr;uint;uint;uint;uint;uint;uint;uint;uint')
        DllStructSetData($tParams[$i], 1, $tData[0].Scan0)
        DllStructSetData($tParams[$i], 2, $tData[1].Scan0)
        DllStructSetData($tParams[$i], 3, 0)
        DllStructSetData($tParams[$i], 4, $iLength)
        DllStructSetData($tParams[$i], 5, $aSize[2])
        DllStructSetData($tParams[$i], 6, $aHeight[$i])
        DllStructSetData($tParams[$i], 7, $aSize[2])
        DllStructSetData($tParams[$i], 8, $aSize[3])
        DllStructSetData($tParams[$i], 9, $iRadius)
        If $fAccurate Then
            DllStructSetData($tParams[$i],10, 1)
        Else
            DllStructSetData($tParams[$i],10, 2)
        EndIf
        $iLength+= $aHeight[$i]
        $aResult = DllCall('kernel32.dll', 'handle', 'CreateThread', 'ptr', 0, 'dword_ptr', 0, 'ptr', $pProc[0], 'struct*', $tParams[$i], 'dword', 0, 'ptr', 0)
        If (Not @Error) And ($aResult[0]) Then
            $hThread[$i] = $aResult[0]
        Else
            $hThread[$i] = 0
        EndIf
    Next
    While 1
        $iLength = 0
        For $i = 0 To $iThread - 1
            If $hThread[$i] Then
                $aResult = DllCall('kernel32.dll', 'bool', 'GetExitCodeThread', 'handle', $hThread[$i], 'dword*', 0)
                If (@Error) Or (Not $aResult[0]) Or ($aResult[2] <> 259) Then
                    DllCall('kernel32.dll', 'bool', 'CloseHandle', 'handle', $hThread[$i])
                    $hThread[$i] = 0
                Else
                    $iLength += 1
                EndIf
            EndIf
        Next
        If Not $iLength Then
            ExitLoop
        EndIf
    WEnd
    $aResult = DllCall('kernel32.dll', 'int', 'VirtualFree', 'ptr', $pProc[0], 'ulong_ptr', 0, 'dword', 0x4000)
    If (@Error) Or (Not $aResult[0]) Then
        ; Nothing
    EndIf
    _GDIPlus_BitmapUnlockBits($hResult, $tData[1])
    _GDIPlus_BitmapUnlockBits($hBitmap, $tData[0])
    Return $hResult
EndFunc   ;==>_GDIPlus_BitmapCreateBlurBitmap

My results (in ms):

450.636964902269
43.2380725602171
151.866555545064

I tried the blur effects to be similar as possible.

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

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  

  • Similar Content

    • Valiante
      By Valiante
      I'm creating a tool which automatically saves screenshots.  I've found that some images appear corrupt after saving.  I've narrowed the source down to screenshots taken from within an RDP session via the Ctrl+Alt+Plus (PrtScn equivalent) and Ctrl+Alt+Minus (Alt+PrtScn equivalent) key combos.
      Here is the example code:
      #include <ClipBoard.au3> #include <GDIPlus.au3> If _ClipBoard_IsFormatAvailable($CF_BITMAP) Then ConsoleWrite("+Bitmap found on Clipboard" & @CRLF) If Not _ClipBoard_Open(0) Then MsgBox(16, "Error", "_ClipBoard_Open failed") Exit EndIf $hClipboardImage = _ClipBoard_GetDataEx($CF_BITMAP) _ClipBoard_Close() _GDIPlus_Startup() $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hClipboardImage) $sCLSID = _GDIPlus_EncodersGetCLSID("JPG") _GDIPlus_ImageSaveToFileEx($hBitmap, @ScriptDir & "\" & TimerInit() & "_Clipboard_Image.jpg", $sCLSID, 0) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_Shutdown() Else MsgBox(48, @ScriptName, "No Bitmap found on Clipboard") EndIf If you copy a local window to the clipboard via Alt+PrtScn the above works fine.  If you copy a window in an RDP session via Ctrl+Alt+Minus it saves the image, but the left-hand edge appears to contain a few pixels sliced off the right-hand side of the bitmap (see two attached images for examples; one good, one bad).  If you paste directly into MSPaint, the image appears correctly, so the clipboard contents is good. It seems to be the process of converting the bitmap handle to an image file via GDIPlus which corrupts it (though I may be wrong about this).
      I've tried inspecting the contents of the clipboard via the _ClipBoard_EnumFormats example and I've noticed the clipboard from the RDP session contains a couple more formats;
      Local:
      Clipboard formats ..: 3 Clipboard format 1 .: Bitmap Clipboard format 2 .: DIB Clipboard format 3 .: DIB V5 RDP:
      Clipboard formats ..: 5 Clipboard format 1 .: DataObject Clipboard format 2 .: DIB Clipboard format 3 .: DIB V5 Clipboard format 4 .: Ole Private Data Clipboard format 5 .: Bitmap However the _ClipBoard_GetDataEx function is specifying the $CF_BITMAP constant for the format, which both instances contain, so I'm not sure the extra formats have any impact?
      I've tried using a combination of _ClipBoard_GetDataEx($CF_DIB) and _GDIPlus_BitmapCreateFromMemory in an effort to write the binary directly to a file, instead of using a bitmap handle, however this doesn't appear to work and just returns a zero and doesn't set @error to anything, which isn't covered in the help file (a failure should return a zero and set the @error level to something).
      I've hunted around the forums and tried everything I can think of. I can normally figure most things out without posting but I've been dipping in and out of this script for a few months now and have finally thrown in the towel and must ask you guys for help, which isn't a decision I take lightly.  Your help is, as always, greatly appreciated.


    • UEZ
      By UEZ
      Here another example to mark the desktop to get the marked region for capturing. This example is not perfect and not very fast (room for improvements).
      ;coded by UEZ build 2018-11-30 beta ;code cleanup up mLipok #include <APISysConstants.au3> #include <Array.au3> #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <WinAPIGdi.au3> #include <WinAPISysWin.au3> #include <WindowsConstants.au3> Global $__g_hGUI_MarkArea, $__g_hGUI_Bg, $__g_iLabel_TL, $__g_iLabel_TM, $__g_iLabel_TR, $__g_iLabel_LM, $__g_iLabel_RM, $__g_iLabel_BL, $__g_iLabel_BM, _ $__g_iLabel_BR, $__g_iOldCursor, $__g_iW, $__g_iH, $__g_iColor_ResizeDots = 0xFFFFFF, $__g_iBorder = 4, $__g_bSelectionDone = False Global $aRect = _GDIPlus_MarkScreenRegionAnimated() _ArrayDisplay($aRect, "Marked area coordinates") Func _GDIPlus_MarkScreenRegionAnimated($bAnim = True) _GDIPlus_Startup() Local Const $hFullScreen = WinGetHandle("[TITLE:Program Manager;CLASS:Progman]") Local Const $aFullScreen = WinGetPos($hFullScreen) $__g_hGUI_Bg = GUICreate("", $aFullScreen[2], $aFullScreen[3], $aFullScreen[0], $aFullScreen[1], BitOR($WS_CLIPCHILDREN, $WS_POPUP), $WS_EX_TOPMOST) ;to avoid cursor flickering and for proper control read WinSetTrans($__g_hGUI_Bg, "", 0x01) $__g_hGUI_MarkArea = GUICreate("", 1, 1, -1, -1, $bAnim ? $WS_POPUP : BitOR($WS_POPUP, $WS_BORDER), BitOR($WS_EX_TOPMOST, $WS_EX_LAYERED), $__g_hGUI_Bg) GUISetBkColor(0xABCDEF, $__g_hGUI_MarkArea) If Not $bAnim Then $__g_iColor_ResizeDots = 0xFF0000 $__g_iLabel_TL = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;top left GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_TM = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;top mid GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_TR = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;top right GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_LM = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;left mid GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_RM = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;right mid GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_BL = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;bottom left GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_BM = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;bottom mid GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) $__g_iLabel_BR = GUICtrlCreateLabel("", 0, 0, $__g_iBorder, $__g_iBorder) ;bottom right GUICtrlSetResizing(-1, $GUI_DOCKSIZE) GUICtrlSetBkColor(-1, $__g_iColor_ResizeDots) GUISetState(@SW_SHOWNA, $__g_hGUI_Bg) GUISetState(@SW_SHOW, $__g_hGUI_MarkArea) $__g_iOldCursor = MouseGetCursor() GUISetCursor(3, 1, $__g_hGUI_Bg) GUISetCursor(3, 1, $__g_hGUI_MarkArea) _WinAPI_SetLayeredWindowAttributes($__g_hGUI_MarkArea, 0xABCDEF, 0xF0) Local $aMPos, $aPrevMPos[2] = [MouseGetPos(0) + 1, MouseGetPos(1) + 1], $iID, $aCI, $iX, $iY, $aOldWinPos, $aOldMPos, $bMoved Local $aGUIStartPos, $iKey_Exit = GUICtrlCreateButton("", $aFullScreen[0] - 10, $aFullScreen[1] - 10, 1, 1), $aAccelKeys[1][2] = [["{ENTER}", $iKey_Exit]] GUISetAccelerators($aAccelKeys, $__g_hGUI_Bg) GUISetAccelerators($aAccelKeys, $__g_hGUI_MarkArea) #forceref $bMoved Do Switch GUIGetMsg() Case $GUI_EVENT_CLOSE, $iKey_Exit If $bAnim Then GUIRegisterMsg($WM_TIMER, "") DllCall("user32.dll", "bool", "KillTimer", "hwnd", $__g_hGUI_MarkArea, "uint_ptr", $iID) GUIRegisterMsg($WM_ERASEBKGND, "") EndIf _GDIPlus_Shutdown() Local $aResult = WinGetPos($__g_hGUI_MarkArea) $aResult[2] = WinGetClientSize($__g_hGUI_MarkArea)[0] $aResult[3] = WinGetClientSize($__g_hGUI_MarkArea)[1] GUIDelete($__g_hGUI_MarkArea) GUIDelete($__g_hGUI_Bg) If Not $__g_bSelectionDone Then $aResult = 0 Return $aResult EndSwitch $aMPos = MouseGetPos() If ($aMPos[0] <> $aPrevMPos[0] Or $aMPos[1] <> $aPrevMPos[1]) And (Not $__g_bSelectionDone) Then WinMove($__g_hGUI_MarkArea, "", $aMPos[0], $aMPos[1]) $aPrevMPos = $aMPos EndIf $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) If $aCI[2] And (Not $__g_bSelectionDone) Then $aGUIStartPos = WinGetPos($__g_hGUI_MarkArea) If $bAnim Then GUIRegisterMsg($WM_ERASEBKGND, "WM_ERASEBKGND") GUIRegisterMsg($WM_TIMER, "PlayBorderAnim") $iID = DllCall("User32.dll", "uint_ptr", "SetTimer", "hwnd", $__g_hGUI_MarkArea, "uint_ptr", 1, "uint", 50, "ptr", 0)[0] EndIf While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) $aMPos = MouseGetPos() $__g_iW = Abs($aMPos[0] - $aGUIStartPos[0]) + 1 $__g_iH = Abs($aMPos[1] - $aGUIStartPos[1]) + 1 If $aMPos[0] < $aGUIStartPos[0] Then $iX = $aMPos[0] Else $iX = $aGUIStartPos[0] EndIf If $aMPos[1] < $aGUIStartPos[1] Then $iY = $aMPos[1] Else $iY = $aGUIStartPos[1] EndIf WinMove($__g_hGUI_MarkArea, "", $iX, $iY, $__g_iW, $__g_iH) UpdateCtrlPos($bAnim) WEnd $__g_bSelectionDone = True GUISetCursor(3, 1, $__g_hGUI_MarkArea) ElseIf $aCI[3] And $__g_bSelectionDone Then $aGUIStartPos = WinGetPos($__g_hGUI_MarkArea) If _WinAPI_PtInRectEx(MouseGetPos(0), MouseGetPos(1), $aGUIStartPos[0], $aGUIStartPos[1], $aGUIStartPos[0] + $aGUIStartPos[2], $aGUIStartPos[1] + $aGUIStartPos[3]) Then $aMPos = MouseGetPos() $aGUIStartPos = WinGetPos($__g_hGUI_MarkArea) While $aCI[3] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aGUIStartPos[0] - ($aMPos[0] - MouseGetPos(0)), $aGUIStartPos[1] - ($aMPos[1] - MouseGetPos(1)), $__g_iW, $__g_iH) GUISetCursor(0, 1, $__g_hGUI_Bg) GUISetCursor(0, 1, $__g_hGUI_MarkArea) WEnd GUISetCursor(3, 1, $__g_hGUI_Bg) GUISetCursor(3, 1, $__g_hGUI_MarkArea) EndIf EndIf If $__g_bSelectionDone Then $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) If @error Then ContinueLoop Switch $aCI[4] Case $__g_iLabel_TL GUISetCursor(12, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", MouseGetPos(0), MouseGetPos(1), $aOldWinPos[2] + ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3] + ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_BR GUISetCursor(12, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aOldWinPos[0], $aOldWinPos[1], $aOldWinPos[2] - ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3] - ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_TR GUISetCursor(10, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aOldWinPos[0], MouseGetPos(1), $aOldWinPos[2] - ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3] + ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_BL GUISetCursor(10, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", MouseGetPos(0), $aOldWinPos[1], $aOldWinPos[2] + ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3] - ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_LM GUISetCursor(13, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", MouseGetPos(0), $aOldWinPos[1], $aOldWinPos[2] + ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3]) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_RM GUISetCursor(13, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aOldWinPos[0], $aOldWinPos[1], $aOldWinPos[2] - ($aOldMPos[0] - MouseGetPos(0)), $aOldWinPos[3]) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_TM GUISetCursor(11, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aOldWinPos[0], MouseGetPos(1), $aOldWinPos[2], $aOldWinPos[3] + ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case $__g_iLabel_BM GUISetCursor(11, 1, $__g_hGUI_MarkArea) If $aCI[2] Then $aOldWinPos = WinGetPos($__g_hGUI_MarkArea) $aOldMPos = MouseGetPos() While $aCI[2] * Sleep(10) $aCI = GUIGetCursorInfo($__g_hGUI_MarkArea) WinMove($__g_hGUI_MarkArea, "", $aOldWinPos[0], $aOldWinPos[1], $aOldWinPos[2], $aOldWinPos[3] - ($aOldMPos[1] - MouseGetPos(1))) WEnd UpdateCtrlPos($bAnim) EndIf Case Else GUISetCursor(3, 1, $__g_hGUI_MarkArea) EndSwitch EndIf Until False EndFunc ;==>_GDIPlus_MarkScreenRegionAnimated Func UpdateCtrlPos($bAnim = True) Local Const $aGUIStartPos = WinGetPos($__g_hGUI_MarkArea) If $__g_bSelectionDone And $bAnim Then GUIRegisterMsg($WM_TIMER, "") $__g_iW = $aGUIStartPos[2] $__g_iH = $aGUIStartPos[3] ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_TL, 0, 0, $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_TM, ($__g_iW - $__g_iBorder) / 2, 0, $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_TR, ($__g_iW - $__g_iBorder - $__g_iBorder / 2), 0, $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_LM, 0, ($__g_iH - $__g_iBorder) / 2, $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_RM, ($__g_iW - $__g_iBorder - $__g_iBorder / 2), ($__g_iH - $__g_iBorder) / 2, $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_BL, 0, ($__g_iH - $__g_iBorder - $__g_iBorder / 2), $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_BM, ($__g_iW - $__g_iBorder) / 2, ($__g_iH - $__g_iBorder - $__g_iBorder / 2), $__g_iBorder, $__g_iBorder) ControlMove($__g_hGUI_MarkArea, "", $__g_iLabel_BR, ($__g_iW - $__g_iBorder - $__g_iBorder / 2), ($__g_iH - $__g_iBorder - $__g_iBorder / 2), $__g_iBorder, $__g_iBorder) If $__g_bSelectionDone And $bAnim Then GUIRegisterMsg($WM_TIMER, "PlayBorderAnim") EndFunc ;==>UpdateCtrlPos Func PlayBorderAnim() Local $aWinPos = WinGetClientSize($__g_hGUI_MarkArea), $iW = $aWinPos[0], $iH = $aWinPos[1] Local Static $fOffset = 0 Local Const $iSize = $__g_iBorder / 2 Local Const $hDC = _WinAPI_GetDC($__g_hGUI_MarkArea) Local Const $hHBitmap = _WinAPI_CreateCompatibleBitmap($hDC, $iW, $iH) Local Const $hDC_backbuffer = _WinAPI_CreateCompatibleDC($hDC) Local Const $DC_obj = _WinAPI_SelectObject($hDC_backbuffer, $hHBitmap) Local Const $hCanvas = _GDIPlus_GraphicsCreateFromHDC($hDC_backbuffer) Local Const $hPen = _GDIPlus_PenCreate(0xFF0178D7, $iSize), $hPen2 = _GDIPlus_PenCreate(0xFFFFFFFF, $iSize), _ $hBrush = _GDIPlus_BrushCreateSolid(0xFF000000 + $__g_iColor_ResizeDots), $hPen3 = _GDIPlus_PenCreate(0xFF000000) _GDIPlus_PenSetDashStyle($hPen, $GDIP_DASHSTYLEDASHDOT) _GDIPlus_GraphicsClear($hCanvas, 0xFFABCDEF) ;for faster performance direct dll calls DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen2, "float", 1 + $iSize, "float", 1 + $iSize, "float", $iW - 2 * $iSize - 2, "float", $iH - 2 * $iSize - 2) DllCall($__g_hGDIPDll, "int", "GdipSetPenDashOffset", "handle", $hPen, "float", $fOffset) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen, "float", 1 + $iSize, "float", 1 + $iSize, "float", $iW - 2 * $iSize - 2, "float", $iH - 2 * $iSize - 2) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", 0, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", 0, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", ($iW - $__g_iBorder) / 2, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", ($iW - $__g_iBorder) / 2, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", ($iW - $__g_iBorder) - 2, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", ($iW - $__g_iBorder) - 2, "float", 0, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", 0, "float", ($iH - $__g_iBorder) / 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", 0, "float", ($iH - $__g_iBorder) / 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", ($iW - $__g_iBorder) - 2, "float", ($iH - $__g_iBorder) / 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", ($iW - $__g_iBorder) - 2, "float", ($iH - $__g_iBorder) / 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", 0, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", 0, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", ($iW - $__g_iBorder) / 2, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", ($iW - $__g_iBorder) / 2, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipFillRectangle", "handle", $hCanvas, "handle", $hBrush, "float", ($iW - $__g_iBorder) - 2, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) DllCall($__g_hGDIPDll, "int", "GdipDrawRectangle", "handle", $hCanvas, "handle", $hPen3, "float", ($iW - $__g_iBorder) - 2, "float", ($iH - $__g_iBorder) - 2, "float", $__g_iBorder + 1, "float", $__g_iBorder + 1) _WinAPI_BitBlt($hDC, 0, 0, $iW, $iH, $hDC_backbuffer, 0, 0, $SRCCOPY) $fOffset += 0.5 _GDIPlus_GraphicsDispose($hCanvas) _WinAPI_SelectObject($hDC_backbuffer, $DC_obj) _WinAPI_DeleteDC($hDC_backbuffer) _WinAPI_DeleteObject($hHBitmap) _WinAPI_ReleaseDC($__g_hGUI_MarkArea, $hDC) _GDIPlus_PenDispose($hPen) _GDIPlus_PenDispose($hPen2) _GDIPlus_PenDispose($hPen3) _GDIPlus_BrushDispose($hBrush) EndFunc ;==>PlayBorderAnim Func WM_ERASEBKGND($hWnd, $iMsgm, $wParam, $lParam) ;suppress repainting to avoid flickering but causes some other side effects #forceref $iMsgm, $wParam, $lParam, $hWnd Local Const $hBrush = _WinAPI_CreateSolidBrush(0xEFCDAB) ;BGR format ;~ _WinAPI_RedrawWindow($__g_hGUI_MarkArea, 0, 0, BitOR($RDW_NOERASE, $RDW_NOCHILDREN, $RDW_NOFRAME, $RDW_VALIDATE)) _WinAPI_SetClassLongEx($__g_hGUI_MarkArea, $GCL_HBRBACKGROUND, $hBrush) _WinAPI_DeleteObject($hBrush) Return 0 EndFunc ;==>WM_ERASEBKGND  
      Just press the lmb and move your mouse. When lmb is released you can adjust the size of the window by dragging the white rectangle to any direction. Rmb will move the marked area.
      Press ESC to get the coordinates of the marked region.
      If you have any improvements, please post it here.
       
      Tested on Win10 x64 only.
       
    • badcoder123
      By badcoder123
      Hey, All!
       
      I was looking into the help file at all the drawing utilities and I was wondering if you draw a translucent line that follows your cursor. Upon looking for ideas I came across this thread (1.0) and saw UEZ's response. I also came across another post that UEZ replied to and found this reply (1.1) where he shows how you can draw on the desktop. This is what I'm looking for however I'd still like to be able to interact with a designated application and have the line/curve/vector passively follow it. Obviously we don't move our cursor very linearly so it would have to be able to draw on vectors. Am I over complicating this? 
      Any ideas or starting points I should look more into? 
       
       
       
      1.0
      #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> Global Const $aFullScreen = WinGetPos(WinGetHandle("[TITLE:Program Manager;CLASS:Progman]")) Global $iHeight = 4 Global Const $hGUI = GUICreate("Screen Ruler Underline for free :-)", $aFullScreen[2], $iHeight, $aFullScreen[0], MouseGetPos(1), $WS_POPUP, BitOR($WS_EX_TOPMOST, $WS_EX_TRANSPARENT)) GUISetBkColor(0x000000) WinSetTrans($hGUI, "", 0xA0) GUISetState() HotKeySet("{ESC}", "_Exit") Do WinMove($hGUI, "", $aFullScreen[0], MouseGetPos(1)) Until Not Sleep(50) Func _Exit() GUIDelete() Exit EndFunc _____________
      1.1
      #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPI.au3> AutoItSetOption("GUIOnEventMode", 1) Global $hGUI, $hDC, $hPen, $obj_orig $hGUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP) WinSetTrans($hGUI, "", 1) GUISetState() _line() Func _line() $hDC = _WinAPI_GetWindowDC(0) ; DC of entire screen (desktop) $hPen = _WinAPI_CreatePen($PS_SOLID, 2, 0x00ff) $obj_orig = _WinAPI_SelectObject($hDC, $hPen) GUISetOnEvent($GUI_EVENT_PRIMARYDOWN, "Draw", $hGUI) GUISetOnEvent(-3, "_Exit") Do Until Not Sleep(1000) EndFunc ;==>_line Func Draw() Local $aMC, $mxo, $myo $aMC = GUIGetCursorInfo($hGUI) Do GUISetCursor(0, 1, 0) $mxo = $aMC[0] $myo = $aMC[1] $aMC = GUIGetCursorInfo($hGUI) If $mxo <> $aMC[0] Or $myo <> $aMC[1] Then _WinAPI_DrawLine($hDC, $aMC[0], $aMC[1], $mxo, $myo) _WinAPI_RedrawWindow(_WinAPI_GetDesktopWindow(), 0, 0, $RDW_INVALIDATE) $mxo = $aMC[0] $myo = $aMC[1] EndIf Sleep(10) Until Not $aMC[2] EndFunc Func _Exit() _WinAPI_SelectObject($hDC, $obj_orig) _WinAPI_DeleteObject($hPen) _WinAPI_ReleaseDC(0, $hDC) Exit EndFunc  
    • Pricehacker
      By Pricehacker
      Hello,
      I am making a program where the button is an image that "changes" when specific conditions are fullfilled. Problem is that these images have different dimensions and when a smaller picture is displayed over a bigger one both will be seen, therefore i would like the images to be hidden, invincible or, alternatively, deleted.
      I have tried using _GDIPlus_GraphicsClear() with no luck
      However that might just be me not using it right as im quite new to autoit
      Here is the code if you want to test run it:
      Thanks to everyone helping!
×