Jump to content

Image Editing by Pixels


Recommended Posts

I'm trying to blur an image, but I can't think of how to accomplish this with the functions I see in the help file.

So far, the best I can come up with is to use PixelGetColor on every pixel to read it into an array, then after processing, BitBlt each individual pixel to my destination.

I'm working with a 400x400 image and I would like to get the data transfered as quickly as possible, but that's 320,000 calls to PixelGetColor/BitBlt and the image still needs to be processed; also it just doesn't feel like the proper way to do things, especially the 1-pixel block transfer.

Is there a better way?

Link to comment
Share on other sites

  • Moderators

borderLine,

Welcome to the AutoIt forum. :mellow: Sounds like a good time to enter the world of GDI. :P

This script lets you select an area of the screen or an existing bitmap and then it will invert the image. You should be able to amend it fairly easily to your needs as it deals with the image pixel by pixel - look around line 150 for that section:

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <WinAPI.au3>
#Include <Color.au3>
#Include <ScreenCapture.au3>
#Include <Misc.au3>

; Credit: Malkey for the basic GDI code

Global $iTolerance = 30, $iX1, $iY1, $iX2, $iY2, $fType = ""

; Create GUI
$hMain_GUI = GUICreate("Invert BMP", 240, 150)

$hLabel_1 = GUICtrlCreateLabel("First mark the area to invert or select a BMP", 10, 10, 260, 20)

$hRect_Button   = GUICtrlCreateButton("Mark Area",   10, 40, 80, 30)
$hChoose_Button = GUICtrlCreateButton("Choose BMP", 150, 40, 80, 30)

$hLabel_2 = GUICtrlCreateLabel("", 160, 90, 70, 20)

$hAction_Button = GUICtrlCreateButton("Invert",      150,  110, 80, 30)
GUICtrlSetState(-1, $GUI_DISABLE)
$hCancel_Button = GUICtrlCreateButton("Cancel",   10, 110, 80, 30)

GUISetState()

While 1

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE, $hCancel_Button
            GUIDelete($hMain_GUI)
            Exit
        Case $hRect_Button
            GUISetState(@SW_HIDE, $hMain_GUI)
            Mark_Rect()
            GUISetState(@SW_SHOW, $hMain_GUI)
            GUICtrlSetState($hAction_Button, $GUI_ENABLE)
            GUICtrlSetData($hLabel_1, "")
            GUICtrlSetData($hLabel_2, "Now Invert!")
            $fType = "Rect"
        Case $hChoose_Button
            $sBMP_Path = FileOpenDialog("Select BMP to invert", "C:\", "Bitmaps (*.bmp)", 2)
            If @error Then
                MsgBox(64, "Info", "No BMP selected")
            Else
                GUICtrlSetState($hAction_Button, $GUI_ENABLE)
                GUICtrlSetData($hLabel_1, "")
                GUICtrlSetData($hLabel_2, "Now Invert!")
                $fType = "File"
            EndIf
        Case $hAction_Button
            GUIDelete($hMain_GUI)
            ExitLoop
    EndSwitch

WEnd

; Capture selected area if needed
If $fType = "Rect" Then
    $sBMP_Path = @ScriptDir & "\TestNormal.bmp"
    GUISetState(@SW_HIDE, $hMain_GUI)
    _ScreenCapture_Capture($sBMP_Path, $iX1, $iY1, $iX2, $iY2, False)
EndIf

; Load original image
_GDIPlus_Startup()
$hImage = _GDIPlus_ImageLoadFromFile($sBMP_Path)
If @error Then
    MsgBox(16, "Error", "Could not load BMP file")
    _GDIPlus_Shutdown()
    Exit
EndIf

Global $GuiSizeX = _GDIPlus_ImageGetWidth($hImage)
Global $GuiSizeY = _GDIPlus_ImageGetHeight($hImage)

; Display original image
$hBitmap_GUI = GUICreate("Original Bitmap", $GuiSizeX, $GuiSizeY, 100, 100)
GUISetState()

; Create Double Buffer, so the doesn't need to be repainted on PAINT-Event
$hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hBitmap_GUI)
$hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($GuiSizeX, $GuiSizeY, $hGraphicGUI)
$hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff)

_GDIPlus_GraphicsDrawImageRect($hGraphic, $hImage, 0, 0, $GuiSizeX, $GuiSizeY)

GUIRegisterMsg(0xF, "MY_PAINT")
GUIRegisterMsg(0x85, "MY_PAINT")
_GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)

; Invert the image
Local $hBitmap = Image_Invert($hBMPBuff, 0, 0, $GuiSizeX, $GuiSizeY)
If _GDIPlus_ImageSaveToFile($hBitmap, @ScriptDir & "\TestInverted.bmp") =  False Then MsgBox(16 , "Error", "Inverted image not created")

WinActivate($hBitmap_GUI)

; Display inverted image
$hInverted_GUI = GUICreate("Inverted Image", $GuiSizeX, $GuiSizeY, 500, 200)
$hPic = GUICtrlCreatePic(@ScriptDir & "\TestInverted.bmp", 0, 0, $GuiSizeX, $GuiSizeY)
GUISetState()

While 1
    If GUIGetMsg() = $GUI_EVENT_CLOSE Then
        _GDIPlus_GraphicsDispose($hGraphic)
        _GDIPlus_Shutdown()
        Exit
    EndIf
WEnd

; -------------

;Func to redraw on PAINT MSG
Func MY_PAINT($hWnd, $msg, $wParam, $lParam)

    ; Check, if the GUI with the Graphic should be repainted
    ; The sequencial order of these two commands is important.
    _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0)
    _WinAPI_RedrawWindow($hBitmap_GUI, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME)) ; , $RDW_ALLCHILDREN
    Return $GUI_RUNDEFMSG

EndFunc   ;==>MY_PAINT

; -------------

Func Image_Invert($hImage2, $iStartPosX = 0, $iStartPosY = 0, $GuiSizeX = Default, $GuiSizeY = Default)

    Local $hBitmap1, $Reslt, $width, $height, $stride, $format, $Scan0, $v_Buffer, $v_Value, $iIW, $iIH
    $iIW = _GDIPlus_ImageGetWidth($hImage2)
    $iIH = _GDIPlus_ImageGetHeight($hImage2)
    If $GuiSizeX = Default Or $GuiSizeX > $iIW - $iStartPosX Then $GuiSizeX = $iIW - $iStartPosX
    If $GuiSizeY = Default Or $GuiSizeY > $iIH - $iStartPosY Then $GuiSizeY = $iIH - $iStartPosY
    $hBitmap1 = _GDIPlus_BitmapCloneArea($hImage2, $iStartPosX, $iStartPosY, $GuiSizeX, $GuiSizeY, $GDIP_PXF32ARGB)

    ProgressOn("Inverting Image", "The image is being processed.", "0 percent", -1, -1, 16)

    $Reslt = _GDIPlus_BitmapLockBits($hBitmap1, 0, 0, $GuiSizeX, $GuiSizeY, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB)

    ;Get the returned values of _GDIPlus_BitmapLockBits ()
    $width = DllStructGetData($Reslt, "width")
    $height = DllStructGetData($Reslt, "height")
    $stride = DllStructGetData($Reslt, "stride")
    $format = DllStructGetData($Reslt, "format")
    $Scan0 = DllStructGetData($Reslt, "Scan0")
    For $i = 0 To $GuiSizeX - 1
        For $j = 0 To $GuiSizeY - 1
            $v_Buffer = DllStructCreate("dword", $Scan0 + ($j * $stride) + ($i * 4))
            ; Get colour value of pixel
            $v_Value = DllStructGetData($v_Buffer, 1)
            ; Invert
            If (Abs(_ColorGetBlue ($v_Value) - 0x80) <= $iTolerance And _  ; Blue
                Abs(_ColorGetGreen($v_Value) - 0x80) <= $iTolerance And _  ; Green
                Abs(_ColorGetRed  ($v_Value) - 0x80) <= $iTolerance) Then  ; Red
                DllStructSetData($v_Buffer, 1, BitAND((0x7F7F7F + $v_Value) , 0xFFFFFF))
            Else
                DllStructSetData($v_Buffer, 1, BitXOR($v_Value ,0xFFFFFF))
            EndIf
        Next
        Local $iProgress = Int(100 * $i / ($GuiSizeX))
        ProgressSet(1 + $iProgress, $iProgress & " percent")
        ProgressSet($iProgress, $iProgress & " percent")
    Next
    _GDIPlus_BitmapUnlockBits($hBitmap1, $Reslt)

    ProgressOff()
    Return $hBitmap1

EndFunc   ;==>Image_Invert

; -------------

Func Mark_Rect()

    Local $aMouse_Pos, $hMask, $hMaster_Mask, $iTemp
    Local $UserDLL = DllOpen("user32.dll")

    ; Create transparent GUI with Cross cursor
    $hCross_GUI = GUICreate("Test", @DesktopWidth, @DesktopHeight - 20, 0, 0, $WS_POPUP, $WS_EX_TOPMOST)
    WinSetTrans($hCross_GUI, "", 8)
    GUISetState(@SW_SHOW, $hCross_GUI)
    GUISetCursor(3, 1, $hCross_GUI)

    Global $hRectangle_GUI = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
    GUISetBkColor(0x000000)

    ; Wait until mouse button pressed
    While Not _IsPressed("01", $UserDLL)
        Sleep(10)
    WEnd

    ; Get first mouse position
    $aMouse_Pos = MouseGetPos()
    $iX1 = $aMouse_Pos[0]
    $iY1 = $aMouse_Pos[1]

    ; Draw rectangle while mouse button pressed
    While _IsPressed("01", $UserDLL)

        $aMouse_Pos = MouseGetPos()

        $hMaster_Mask = _WinAPI_CreateRectRgn(0, 0, 0, 0)
        $hMask = _WinAPI_CreateRectRgn($iX1,  $aMouse_Pos[1], $aMouse_Pos[0],  $aMouse_Pos[1] + 1) ; Bottom of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        _WinAPI_DeleteObject($hMask)
        $hMask = _WinAPI_CreateRectRgn($iX1, $iY1, $iX1 + 1, $aMouse_Pos[1]) ; Left of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        _WinAPI_DeleteObject($hMask)
        $hMask = _WinAPI_CreateRectRgn($iX1 + 1, $iY1 + 1, $aMouse_Pos[0], $iY1) ; Top of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        _WinAPI_DeleteObject($hMask)
        $hMask = _WinAPI_CreateRectRgn($aMouse_Pos[0], $iY1, $aMouse_Pos[0] + 1,  $aMouse_Pos[1]) ; Right of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        _WinAPI_DeleteObject($hMask)
        ; Set overall region
        _WinAPI_SetWindowRgn($hRectangle_GUI, $hMaster_Mask)

        If WinGetState($hRectangle_GUI) < 15 Then GUISetState()
        Sleep(10)

    WEnd

    ; Get second mouse position
    $iX2 = $aMouse_Pos[0]
    $iY2 = $aMouse_Pos[1]

    ; Set in correct order if required
    If $iX2 < $iX1 Then
        $iTemp = $iX1
        $iX1 = $iX2
        $iX2 = $iTemp
    EndIf
    If $iY2 < $iY1 Then
        $iTemp = $iY1
        $iY1 = $iY2
        $iY2 = $iTemp
    EndIf

    GUIDelete($hRectangle_GUI)
    GUIDelete($hCross_GUI)
    DllClose($UserDLL)

EndFunc   ;==>Mark_Rect

I hope this helps, but I will admit straight away that I am far from a GDI expert. However, there are plenty of them around if you run into any problems. :(

M23

P.S. In case you are wondering why I wanted to invert an image in the first place - some OCR apps give better results white on black than black on white. :lol:

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Check this approach out.

Note: Should you press the "Blur Blur" button, the "Escape" keyboard button returns things to normal.

The "Blur Blur" button blurs the already blurred desktop in a loop. It is a bit like watching paint dry, but in time the primary colours appear in random shapes with clarity in cycles.

Earlier today/tonight, the "Blur Blur" loop was being randomly interrupted by refresh or re-paint messages to random parts of the desktop. It is fine now, until the screen saver kicked in.

#include <GUIConstantsEx.au3>
#include <ScreenCapture.au3>
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
#include <IE.au3>

;http://www.autoitscript.com/forum/index.php?showtopic=61057&st=0&p=458911&hl=SetInterpolationMode&#entry458911
Opt('MustDeclareVars', 1)
HotKeySet("{ESC}", "End")
Global $hGUI1, $DeskTopGui = True, $UseImageFile = False, $hGraphic1, $hBMP, $bSave = False, $checkBl, $oIE
Global $endBBlur = False, $Num = 0

Local $hGUI, $InpStretch, $LabInterpol, $cInputIM, $LabPixOff, $InpPixOfset, $LabSmooth, $cInpSmooth, $AutoBlur, $cBtnBlur
Local $DispDeskGui, $ImageToUse, $SaveImage, $imageFile, $cBtnClear

$hGUI = GUICreate("Blur Control", 200, 215, @DesktopWidth - 270, @DesktopHeight - 280, $WS_OVERLAPPEDWINDOW, $WS_EX_TOPMOST)
GUISetBkColor(0xBBBBFF, $hGUI)

GUICtrlCreateLabel("Stretch Ratio", 20, 10, 100, 20)
$InpStretch = GUICtrlCreateInput("2.0", 135, 5, 50, 20)

$LabInterpol = GUICtrlCreateLabel("Interpolation Mode", 20, 35, 120, 20)
GUICtrlSetColor($LabInterpol, 0x0000FF)
GUICtrlSetFont($LabInterpol, 9, 800, 4)
GUICtrlSetTip($LabInterpol, " Link about InterpolationMode at" & @CRLF & _
        " http://msdn2.microsoft.com/en-us/library/ms534141(VS.85).aspx)")

$cInputIM = GUICtrlCreateInput("7", 135, 30, 50, 20)
GUICtrlSetTip($cInputIM, " Possible values " & @CRLF & " 0 - 8?")

$LabPixOff = GUICtrlCreateLabel("Pixel Offset Mode", 20, 60, 100, 20)
GUICtrlSetColor($LabPixOff, 0x0000FF)
GUICtrlSetFont($LabPixOff, 9, 800, 4)
GUICtrlSetTip($LabPixOff, " Link about PixelOffsetMode at" & @CRLF & _
        " http://msdn2.microsoft.com/en-us/library/ms534169(VS.85).aspx)")

$InpPixOfset = GUICtrlCreateInput("2", 135, 55, 50, 20)
GUICtrlSetTip($InpPixOfset, " Possible values " & @CRLF & " 0 - 5? ")

$LabSmooth = GUICtrlCreateLabel("Smoothing Mode", 20, 85, 100, 20)
GUICtrlSetColor($LabSmooth, 0x0000FF)
GUICtrlSetFont($LabSmooth, 9, 800, 4)
GUICtrlSetTip($LabSmooth, " Link about SmoothingMode at" & @CRLF & _
        " http://msdn2.microsoft.com/en-us/library/ms534173(VS.85).aspx")

$cInpSmooth = GUICtrlCreateInput("4", 135, 80, 50, 20)
GUICtrlSetTip($cInpSmooth, " Possible values " & @CRLF & " 0 - 7?")

$checkBl = GUICtrlCreateCheckbox("Blur Operation    ", 20, 105, 95, 20, 0x0120)
GUICtrlSetState($checkBl, $GUI_CHECKED)
GUICtrlSetTip($checkBl, " Toggle Blur / Magnify button " & @CRLF)

$AutoBlur = GUICtrlCreateButton("Blur Blur", 120, 105, 65, 20)
GUICtrlSetTip($AutoBlur, " Press Esc to exit this blur the blurred loop " & @CRLF)

$cBtnBlur = GUICtrlCreateButton("Blur", 20, 130, 80, 20)
GUICtrlSetTip($cBtnBlur, " Start blurring operation " & @CRLF & " OR " & @CRLF & "Magnify" & @CRLF)

$cBtnClear = GUICtrlCreateButton("Clear", 100, 130, 80, 20)
GUICtrlSetTip($cBtnClear, "Clear Desktop or GUI window")

$DispDeskGui = GUICtrlCreateButton("Will be Displayed on Desktop", 20, 150, 160, 20)
GUICtrlSetTip($DispDeskGui, " Toggle: " & @CRLF & " Blur entire desktop; OR " & @CRLF & "   Blur image within a GUI/Window " & @CRLF)

$ImageToUse = GUICtrlCreateButton(" Will use image of Desktop", 20, 170, 160, 20)
GUICtrlSetTip($ImageToUse, " Toggle: " & @CRLF & "  Use an image from part of the Desktop; OR " & @CRLF & _
        "   Select an image file when Blur button is pressed " & @CRLF)

$SaveImage = GUICtrlCreateButton("Do NOT Save next GUI image", 20, 190, 160, 20)
GUICtrlSetTip($SaveImage, " Toggle: Save / Do Not Save next GUI/window image generated" & @CRLF & "Will save GDIPlus_Blur.jpg to desktop")

GUISetState()

_GDIPlus_Startup()

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ;If ProcessExists("iexplore.exe") = 0 Then
            _GDIPlus_Shutdown()
            _ScreenClear()
            Exit
        Case $LabInterpol
            ShellExecute("http://msdn2.microsoft.com/en-us/library/ms534141(VS.85).aspx")
        Case $LabPixOff
            ShellExecute("http://msdn2.microsoft.com/en-us/library/ms534173(VS.85).aspx")
        Case $LabSmooth
            ShellExecute("http://msdn2.microsoft.com/en-us/library/ms534173(VS.85).aspx")
        Case $checkBl
            If GUICtrlRead($checkBl) = 4 Then
                GUICtrlSetData($cBtnBlur, "Magnify")
            Else
                GUICtrlSetData($cBtnBlur, "Blur")
            EndIf
        Case $AutoBlur
            If Not $endBBlur Then
                $endBBlur = Not $endBBlur
                $bSave = False
                GUICtrlSetData($SaveImage, "Do NOT Save next GUI image")
                $DeskTopGui = True
                GUICtrlSetData($DispDeskGui, " Will be Displayed on Desktop")
                $UseImageFile = False
                GUICtrlSetData($ImageToUse, " Will use image of Desktop")
                GUICtrlSetData($cBtnBlur, "Blur")
                GUICtrlSetState($checkBl, $GUI_CHECKED)
                Do
                    $Num = Mod($Num + 0.005, 4 * ATan(1))
                    Sleep(200)
                    _ScreenBlur(Round(Sin($Num) * 40 + 0.8, 2))
                Until $endBBlur = False
                _ScreenClear()
                $Num = 0
            EndIf
        Case $cBtnBlur
            _ScreenClear()
            _ScreenBlur(GUICtrlRead($InpStretch), GUICtrlRead($cInputIM), GUICtrlRead($InpPixOfset), GUICtrlRead($cInpSmooth))
        Case $SaveImage
            $bSave = Not $bSave
            If $bSave Then
                GUICtrlSetData($SaveImage, "Save next GUI image generated")
                $DeskTopGui = False
                GUICtrlSetData($DispDeskGui, " Will be Displayed in GUI")
            Else
                GUICtrlSetData($SaveImage, "Do NOT Save next GUI image")
            EndIf
        Case $cBtnClear
            _ScreenClear()
        Case $DispDeskGui
            $DeskTopGui = Not $DeskTopGui
            If $DeskTopGui Then
                GUICtrlSetData($DispDeskGui, " Will be Displayed on Desktop")
                $UseImageFile = False
                GUICtrlSetData($ImageToUse, " Will use image of Desktop")
                $bSave = False
                GUICtrlSetData($SaveImage, "Do NOT Save next GUI image")
            Else
                GUICtrlSetData($DispDeskGui, " Will be Displayed in GUI")
            EndIf
            _ScreenClear()
        Case $ImageToUse
            $UseImageFile = Not $UseImageFile
            If $UseImageFile Then
                GUICtrlSetData($ImageToUse, " Will use loaded image file")
                $DeskTopGui = False
                GUICtrlSetData($DispDeskGui, " Will be Displayed in GUI")
            Else
                GUICtrlSetData($ImageToUse, " Will use image of Desktop")
            EndIf
            _ScreenClear()
    EndSwitch
WEnd

Func _ScreenClear()
    If $hGUI1 <> "" Then
        GUIDelete($hGUI1)
        $hGUI1 = ""
    Else
        _WinAPI_RedrawWindow(_WinAPI_GetDesktopWindow(), 0, 0, $RDW_INVALIDATE + $RDW_UPDATENOW + $RDW_ALLCHILDREN)
    EndIf
EndFunc ;==>_ScreenClear

Func _ScreenBlur($nRatio, $iInterMode = 7, $iPixOffsetMode = 2, $iSmoothMode = 4)
    Local $hImg, $iW, $iH, $hScreenDC, $hScreenGraph, $hImg2, $hMemGraph
    If $DeskTopGui = False Then
        If $UseImageFile = True Then
            ; Image select file dialog
            $imageFile = FileOpenDialog("Open image", @WorkingDir, "Images (*.jpg;*.jpeg;*.gif;*.png;*.bmp)", 1)
            If (@error) Then Return
            $hImg = _GDIPlus_ImageLoadFromFile($imageFile)
            $iW = _GDIPlus_ImageGetWidth($hImg)
            $iH = _GDIPlus_ImageGetHeight($hImg)

        Else ;Use desktop image in GUI
            $hBMP = _ScreenCapture_Capture("", 0, 0, -1, -1, False)
            $hImg = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
            $iW = 400
            $iH = 400
        EndIf
        $hGUI1 = GUICreate("Original", $iW, $iH, 20, 20, $WS_CAPTION)
        GUISetState()
        $hGraphic1 = _GDIPlus_GraphicsCreateFromHWND($hGUI1)
        _GDIPlus_GraphicsDrawImage($hGraphic1, $hImg, 0, 0)
        $hScreenDC = _WinAPI_GetDC($hGUI1)

    Else ;Use desktop image on desktop
        $hBMP = _ScreenCapture_Capture("", 0, 0, -1, -1, False)
        $hImg = _GDIPlus_BitmapCreateFromHBITMAP($hBMP)
        $iW = @DesktopWidth
        $iH = @DesktopHeight
        $hScreenDC = _WinAPI_GetDC(0)
    EndIf

    $hScreenGraph = _GDIPlus_GraphicsCreateFromHDC($hScreenDC)

    $hImg2 = _GDIPlus_BitmapCloneArea($hImg, 0, 0, $iW / $nRatio, $iH / $nRatio)
    $hMemGraph = _GDIPlus_ImageGetGraphicsContext($hImg2)
    _InterPixelSmooth($hMemGraph)
    _InterPixelSmooth($hScreenGraph)

    If GUICtrlRead($checkBl) = 1 Then _
            _GDIPlus_GraphicsDrawImageRectRect($hMemGraph, $hImg, 0, 0, $iW, $iH, 0, 0, $iW / $nRatio, $iH / $nRatio)
    _GDIPlus_GraphicsDrawImageRectRect($hScreenGraph, $hImg2, 0, 0, $iW / $nRatio, $iH / $nRatio, 0, 0, $iW, $iH)

    If $bSave Then _ScreenCapture_CaptureWnd(@DesktopCommonDir & "\GDIPlus_Blur1.jpg", $hGUI1, 0, 21, $iW + 1, $iH + 22)

    If $hBMP <> "" Then _WinAPI_DeleteObject($hBMP)
    _GDIPlus_ImageDispose($hImg)
    _GDIPlus_ImageDispose($hImg2)
    _GDIPlus_GraphicsDispose($hMemGraph)
    _GDIPlus_GraphicsDispose($hScreenGraph)
    If $hGraphic1 <> "" Then _GDIPlus_GraphicsDispose($hGraphic1)
    _WinAPI_ReleaseDC(0, $hScreenDC)
    Return
EndFunc ;==>_ScreenBlur

Func _InterPixelSmooth($hGraphics, $iInterMode = 7, $iPixOffsetMode = 2, $iSmoothMode = 4)
    Local $aResult
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetInterpolationMode", "hwnd", $hGraphics, "int", $iInterMode)
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetPixelOffsetMode", "hwnd", $hGraphics, "int", $iPixOffsetMode)
    $aResult = DllCall($ghGDIPDll, "int", "GdipSetSmoothingMode", "hwnd", $hGraphics, "int", $iSmoothMode)
    If @error Then Return SetError(@error, @extended, False)
    Return SetError($aResult[0], 0, $aResult[0] = 0)
EndFunc ;==>_InterPixelSmooth

Func End()
    $endBBlur = False
EndFunc ;==>End
Link to comment
Share on other sites

  • Moderators

Malkey,

I wondered if the GDI expert might turn up at some point. :mellow:

And thanks for that wonderful script - the "Blur Blur" button is a great! :(

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

Cool, thanks guys. I got it to work. And as an added bonus, I managed to learn a little about accessing DLL functions while going through your code.

@Malkey: I agree, Blur Blur is cool. I played with that for a while.

@Melba23: What I'm curious about is why you're inverting your image manually when BitBlt does it instantaneously?

Link to comment
Share on other sites

  • Moderators

borderLine,

@Melba23: What I'm curious about is why you're inverting your image manually when BitBlt does it instantaneously?

It was a very old script befero I understood too much about GDI - not that I know much about it now! :( As you already had code to change each pixel I thought an example of pixel-by-pixel GDI code might be helpful. :mellow:

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

  • 2 months later...

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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...