Sign in to follow this  
Followers 0
InunoTaishou

Image Editor using GDI+

2 posts in this topic

Hello again the AutoIt Forums! I've gotten really addicted to the GDIPlus stuff and I'm trying to do more. Trying to create small editor using GDIPlus and I'm a bit lost just getting started.

The main GUI is small, so when I you Snip an area that's larger than the GUI it would only display as large as the GUI (I got around this by setting an event for WM_WINDOWPOSCHANGING but it flickers really badly). I tried doing something by setting the bitmap to a GUICtrlCreatePic control but it still flickered. So essentially I need a way to create a graphics larger than the GUI itself and I don't know how to do something like that. I thought it would have been _GDIPlus_GraphicsCreateFromHDC but it still wasn't create it properly. I did a lot of googling and this topic has a lot of great info in it and I will probably incorporate scrollbars too, later, but UEZ didn't give the secret to resizing! Lol

I've got the source code for vPaint downloaded, and I've started to through some of it (But like the author said, the source code is messy and things are out of order) so it may take a while.

 

#include <GDIPlus.au3>
#include <File.au3>
#include <GUIConstants.au3>
#include <String.au3>
#include <GuiConstantsEx.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <ScreenCapture.au3>
#include <Color.au3>
#include <Misc.au3>
#include <WinAPISys.au3>
#include <GuiToolbar.au3>
#include <GuiImageList.au3>
#include <Array.au3>

AutoItSetOption("GuiOnEventMode", 1)
AutoItSetOption("MustDeclareVars", 1)

HotKeySet("{Esc}", "ClosePixShop")

Global $frm_pixshop_abscoord[4] = [100, 100, 400, 200]
Global $frmPixShop
Global $tlbPixShopToolbar
Global $hWnd_toolbar_image_list
Global $hWnd_dll = DllOpen("user32.dll")
Global $frm_pixshop_state = @SW_HIDE
Global $hWnd_bitmaps[1]
Global $picBitmaps[1]
Global $abscoord_bitmaps[1][2] = [[0, 0]]
Global $abscoord_graphics[4] = [8, 46, 0, 0]
Global $pixshop_buffer[1]
Global Enum $idToolbarStart = 1000, $idMouse, $idSnip, $idCrop, $idText, $idBrush, $idToolbarEnd
Global $hWnd_pixshop_graphics
Global $hWnd_pixshop_bitmap
Global $hWnd_pixshop_buffer

PixShop()

Func PixShop()
    $frmPixShop = GUICreate("PixShop", $frm_pixshop_abscoord[2], $frm_pixshop_abscoord[3], $frm_pixshop_abscoord[0], $frm_pixshop_abscoord[1], $WS_SIZEBOX, $WS_EX_TOPMOST)
    $tlbPixShopToolbar = _GUICtrlToolbar_Create($frmPixShop, $TBSTYLE_TRANSPARENT)
    GUICtrlCreateLabel("", 0, 36, $frm_pixshop_abscoord[2], $frm_pixshop_abscoord[3], -1, $WS_EX_LAYERED)
    GUICtrlSetBkColor(-1, 0x0D0D0D)
    GUICtrlSetResizing(-1, $GUI_DOCKLEFT + $GUI_DOCKTOP + $GUI_DOCKRIGHT + $GUI_DOCKBOTTOM)
    GUISetBkColor(0x535353, $frmPixShop)
    $hWnd_toolbar_image_list = _GUIImageList_Create(24, 24, 5, 5)
    _GUIImageList_AddIcon($hWnd_toolbar_image_list, @ScriptDir & "\Icons\Mouse.ico")
    _GUIImageList_AddIcon($hWnd_toolbar_image_list, @ScriptDir & "\Icons\Snip.ico")
    _GUIImageList_AddIcon($hWnd_toolbar_image_list, @ScriptDir & "\Icons\Crop.ico")
    _GUIImageList_AddIcon($hWnd_toolbar_image_list, @ScriptDir & "\Icons\Text.ico")
    _GUIImageList_AddIcon($hWnd_toolbar_image_list, @ScriptDir & "\Icons\Brush.ico")
    _GUICtrlToolbar_SetImageList($tlbPixShopToolbar, $hWnd_toolbar_image_list)
    _GUICtrlToolbar_SetIndent($tlbPixShopToolbar, 2)
    _GUICtrlToolbar_AddButton($tlbPixShopToolbar, $idMouse, 0)
    _GUICtrlToolbar_AddButton($tlbPixShopToolbar, $idSnip, 1)
    _GUICtrlToolbar_AddButton($tlbPixShopToolbar, $idCrop, 2)
    _GUICtrlToolbar_AddButton($tlbPixShopToolbar, $idText, 3)
    _GUICtrlToolbar_AddButton($tlbPixShopToolbar, $idBrush, 4)
    _GUICtrlToolbar_SetColorScheme($tlbPixShopToolbar, 0x535353, 0x535353)
    _GUICtrlToolbar_CheckButton($tlbPixShopToolbar, $idMouse, True)

    GUISetOnEvent($GUI_EVENT_CLOSE, "ClosePixShop")
    ; Register the WM_GETMINMAXINFO function
    GUIRegisterMsg($WM_GETMINMAXINFO, "WM_GETMINMAXINFO")

    ; Register the WM_NOTIFY function
    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

    GUIRegisterMsg($WM_WINDOWPOSCHANGING, "WM_WINDOWPOSCHANGING")
    GUIRegisterMsg($WM_PAINT, "WM_PAINT")

    GUISetState(@SW_SHOW, $frmPixShop)

    _GDIPlus_Startup()

    While (True)
        Sleep(100)
    WEnd
EndFunc   ;==>PixShop

Func ClosePixShop()
    _GDIPlus_GraphicsDispose($hWnd_pixshop_graphics)
    _GDIPlus_BitmapDispose($hWnd_pixshop_bitmap)
    For $i = 0 To UBound($hWnd_bitmaps) - 1
        _WinAPI_DeleteObject($hWnd_bitmaps[$i])
    Next
    DllClose($hWnd_dll)
    Exit (0)
EndFunc   ;==>ClosePixShop

Func WM_PAINT($hWndFrom, $iMsg, $wParam, $lParam)
    #forceref $hWndFrom, $iMsg, $wParam, $lParam
    DrawPixShopGraphics()
EndFunc   ;==>WM_PAINT

Func WM_NOTIFY($hWndFrom, $iMsg, $wParam, $lParam)
    #forceref $hWndFrom, $iMsg, $wParam, $lParam
    Local $tNMTOOLBAR = DllStructCreate($tagNMTOOLBAR, $lParam)
    Local $tlbCode = DllStructGetData($tNMTOOLBAR, "Code")
    Local $iItem = DllStructGetData($tNMTOOLBAR, "iItem")
    Local $id_checked_button

    If ($tlbCode = $TBN_BEGINDRAG) Then
        If (Not _GUICtrlToolbar_IsButtonChecked($tlbPixShopToolbar, $iItem)) Then
            For $id = $idToolbarStart + 1 To $idToolbarEnd - 1
                If (_GUICtrlToolbar_IsButtonChecked($tlbPixShopToolbar, $id)) Then
                    $id_checked_button = $id
                    _GUICtrlToolbar_CheckButton($tlbPixShopToolbar, $id, False)
                EndIf
            Next

            _GUICtrlToolbar_CheckButton($tlbPixShopToolbar, $iItem, True)
        EndIf

        Switch $iItem
            ; Button pressed was the $idColor button
            Case $idSnip
                Local $abscoord_frm_pixshop = WinGetPos($frmPixShop)

                While (_IsPressed("01", $hWnd_dll))
                    Sleep(10)
                WEnd

                GUISetState(@SW_HIDE, $frmPixShop)

                $hWnd_bitmaps[UBound($hWnd_bitmaps) - 1] = SnipArea($abscoord_bitmaps[UBound($abscoord_bitmaps, $UBOUND_ROWS) - 1][0], $abscoord_bitmaps[UBound($abscoord_bitmaps, $UBOUND_ROWS) - 1][1])
                $pixshop_buffer[UBound($pixshop_buffer) - 1] = "SnippedImage|" & $hWnd_bitmaps[UBound($hWnd_bitmaps) - 1]
                ReDim $hWnd_bitmaps[UBound($hWnd_bitmaps)]

                ReDim $pixshop_buffer[UBound($pixshop_buffer)]

                If ($abscoord_graphics[2] = 0 And $abscoord_graphics[3] = 0) Then
                    $abscoord_graphics[2] = $abscoord_bitmaps[UBound($abscoord_bitmaps, $UBOUND_ROWS) - 1][0]
                    $abscoord_graphics[3] = $abscoord_bitmaps[UBound($abscoord_bitmaps, $UBOUND_ROWS) - 1][1]
                    $pixshop_buffer[UBound($pixshop_buffer) - 1] = "ResizeGraphics|0,0-" & $abscoord_bitmaps[UBound($abscoord_bitmaps, $UBOUND_ROWS) - 1][0] & ',' & $abscoord_bitmaps[UBound($abscoord_bitmaps, $UBOUND_ROWS) - 1][1]
                    ReDim $pixshop_buffer[UBound($pixshop_buffer)]
                    #cs
                        If (IsArray($abscoord_frm_pixshop)) Then
                        If ($abscoord_frm_pixshop[2] < $abscoord_graphics[2]) Then
                        WinMove($frmPixShop, "", $abscoord_frm_pixshop[0], $abscoord_frm_pixshop[1], $abscoord_graphics[2] + 24, $abscoord_frm_pixshop[3])
                        $abscoord_frm_pixshop[2] = $abscoord_graphics[2] + 24
                        EndIf
                        If ($abscoord_frm_pixshop[3] < $abscoord_graphics[3]) Then
                        WinMove($frmPixShop, "", $abscoord_frm_pixshop[0], $abscoord_frm_pixshop[1], $abscoord_frm_pixshop[2], $abscoord_graphics[3] + 46)
                        $abscoord_frm_pixshop[3] = $abscoord_graphics[3] + 54
                        EndIf
                        EndIf
                    #ce
                EndIf

                ReDim $abscoord_bitmaps[UBound($abscoord_bitmaps, $UBOUND_ROWS)][2]

                GUISetState(@SW_SHOW, $frmPixShop)

                ResizePixShopGraphics()
                DrawPixShopGraphics()

                _GUICtrlToolbar_CheckButton($tlbPixShopToolbar, $iItem, False)
                _GUICtrlToolbar_CheckButton($tlbPixShopToolbar, $id_checked_button, True)
            Case $idCrop
                ToolTip("Crop Image")
            Case $idText
                ToolTip("Add Text")
            Case $idBrush
                ToolTip("Brush Image")
        EndSwitch
    EndIf

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func DrawPixShopGraphics()
    Local $hWnd_bitmap = _GDIPlus_BitmapCreateFromHBITMAP($hWnd_bitmaps[0])
    _GDIPlus_GraphicsClear($hWnd_pixshop_buffer, 0x00000000)

    _GDIPlus_GraphicsDrawImageRect($hWnd_pixshop_buffer, $hWnd_bitmap, $abscoord_graphics[0], $abscoord_graphics[1], $abscoord_graphics[2], $abscoord_graphics[3])
    _GDIPlus_ImageDispose($hWnd_bitmap)
    _GDIPlus_GraphicsDrawImage($hWnd_pixshop_graphics, $hWnd_pixshop_bitmap, 0, 0)
EndFunc   ;==>DrawPixShopGraphics

Func SnipArea(ByRef $snipped_image_width, ByRef $snipped_image_height)
    Local $abscoord_mouse
    Local $hMask
    Local $hMaster_Mask
    Local $temp_val
    Local $mouse_x_1
    Local $mouse_y_1
    Local $mouse_x_2
    Local $mouse_y_2

    ToolTip("Left click and drag to select the area", 0, 0)

    Local $frmOverlay = GUICreate("GUI Overlay", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOPMOST)

    WinSetTrans($frmOverlay, "", 1)
    GUISetBkColor(0x000000, $frmOverlay)
    GUISetState(@SW_SHOW, $frmOverlay)
    GUISetCursor(3, 1, $frmOverlay)

    Local $frmSnipArea = GUICreate("GUI Snip", @DesktopWidth, @DesktopHeight, 0, 0, $WS_POPUP, $WS_EX_TOOLWINDOW + $WS_EX_TOPMOST)
    GUISetBkColor(0xFF0000)

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

    ; Get first mouse position
    $abscoord_mouse = MouseGetPos()
    $mouse_x_1 = $abscoord_mouse[0]
    $mouse_y_1 = $abscoord_mouse[1]

    ; Draw rectangle while mouse button pressed
    While _IsPressed("01", $hWnd_dll)
        $abscoord_mouse = MouseGetPos()

        $hMaster_Mask = _WinAPI_CreateRectRgn(0, 0, 0, 0)
        $hMask = _WinAPI_CreateRectRgn($mouse_x_1, $abscoord_mouse[1], $abscoord_mouse[0], $abscoord_mouse[1] + 1) ; Bottom of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        _WinAPI_DeleteObject($hMask)
        $hMask = _WinAPI_CreateRectRgn($mouse_x_1, $mouse_y_1, $mouse_x_1 + 1, $abscoord_mouse[1]) ; Left of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        _WinAPI_DeleteObject($hMask)
        $hMask = _WinAPI_CreateRectRgn($mouse_x_1 + 1, $mouse_y_1 + 1, $abscoord_mouse[0], $mouse_y_1) ; Top of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        _WinAPI_DeleteObject($hMask)
        $hMask = _WinAPI_CreateRectRgn($abscoord_mouse[0], $mouse_y_1, $abscoord_mouse[0] + 1, $abscoord_mouse[1]) ; Right of rectangle
        _WinAPI_CombineRgn($hMaster_Mask, $hMask, $hMaster_Mask, 2)
        _WinAPI_DeleteObject($hMask)
        ; Set overall region
        _WinAPI_SetWindowRgn($frmSnipArea, $hMaster_Mask)

        If WinGetState($frmSnipArea) < 15 Then GUISetState()
        Sleep(10)
    WEnd

    ToolTip("")

    ; Get second mouse position
    $mouse_x_2 = $abscoord_mouse[0]
    $mouse_y_2 = $abscoord_mouse[1]

    ; Set in correct order if required
    If $mouse_x_2 < $mouse_x_1 Then
        $temp_val = $mouse_x_1
        $mouse_x_1 = $mouse_x_2
        $mouse_x_2 = $temp_val
    EndIf

    If $mouse_y_2 < $mouse_y_1 Then
        $temp_val = $mouse_y_1
        $mouse_y_1 = $mouse_y_2
        $mouse_y_2 = $temp_val
    EndIf

    GUIDelete($frmSnipArea)
    GUIDelete($frmOverlay)

    $snipped_image_width = $mouse_x_2 - $mouse_x_1
    $snipped_image_height = $mouse_y_2 - $mouse_y_1

    Return _ScreenCapture_Capture("", $mouse_x_1, $mouse_y_1, $mouse_x_2, $mouse_y_2, False)
EndFunc   ;==>SnipArea

Func ResizePixShopGraphics()
    Local $graphics_width
    Local $graphics_height

    _GDIPlus_GraphicsDispose($hWnd_pixshop_graphics)
    _GDIPlus_BitmapDispose($hWnd_pixshop_bitmap)

    For $i = 0 To UBound($abscoord_bitmaps, $UBOUND_ROWS) - 1
        $graphics_width += $abscoord_bitmaps[$i][0]
        $graphics_height += $abscoord_bitmaps[$i][1]
    Next

    $hWnd_pixshop_graphics = _GDIPlus_GraphicsCreateFromHWND($frmPixShop)
    $hWnd_pixshop_bitmap = _GDIPlus_BitmapCreateFromGraphics($graphics_width, $graphics_height, $hWnd_pixshop_graphics)
    $hWnd_pixshop_buffer = _GDIPlus_ImageGetGraphicsContext($hWnd_pixshop_bitmap)
    _GDIPlus_GraphicsSetSmoothingMode($hWnd_pixshop_buffer, $GDIP_SMOOTHINGMODE_HIGHQUALITY)
    _GDIPlus_GraphicsSetTextRenderingHint($hWnd_pixshop_graphics, $GDIP_TEXTRENDERINGHINT_ANTIALIASGRIDFIT)
EndFunc   ;==>ResizePixShopGraphics

Func WM_WINDOWPOSCHANGING($hWndFrom, $iMsg, $wParam, $lParam)
    #forceref $hWndFrom, $iMsg, $wParam, $lParam
    If ($hWndFrom <> $frmPixShop) Then Return $GUI_RUNDEFMSG

    Local $stWinPos = DllStructCreate("uint;uint;int;int;int;int;uint", $lParam)
    Local $iLeft = DllStructGetData($stWinPos, 3)
    Local $iTop = DllStructGetData($stWinPos, 4)
    Local $iWidth = DllStructGetData($stWinPos, 5)
    Local $iHeight = DllStructGetData($stWinPos, 6)

    ResizePixShopGraphics()
    DrawPixShopGraphics()

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_WINDOWPOSCHANGING

Func WM_GETMINMAXINFO($hWndFrom, $iMsg, $wParam, $lParam)
    #forceref $hWndFrom, $iMsg, $wParam, $lParam
    Local $tagMaxinfo = DllStructCreate("int;int;int;int;int;int;int;int;int;int", $lParam)

    DllStructSetData($tagMaxinfo, 7, 300) ; Set MIN width
    DllStructSetData($tagMaxinfo, 8, 200) ; Set MIN height

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_GETMINMAXINFO

Share this post


Link to post
Share on other sites



Gonna go ahead and bump this, hoping for the best! I haven't made any headway, I did message the author of vPaint but still no response.

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  
Followers 0

  • Similar Content

    • UritOR
      By UritOR
      Hi all,
      I'm trying to find how to draw an image (create a label in mspaint) and save it as .bmp. And set it to be a wallpaper
      I also need to know what wallpaper is use now, for restore it when the script is closed.
      What is the best way to do it? Do I need Gdi+ for it?  I use this code (which I found here in forum) to set a .bmp file as wallpaper:
      Func _ChangeWallpaper($sFile,$iType) ; Changes the wallpaper to $sFilename using $iType as: ; 1 Tiled ; 2 Centered ; 3 Stretched ; any other value (usually 0) unchanged ; ; Returns ; 0 if everything is allright. ; -1 if $sFile does not exist. @error is set to 1 ; -2 if £sFile is not a .bmp file. @error is set to 2 If Not FileExists($sFile) Then SetError(1) Return -1 EndIf If StringTrimLeft($sFile,StringInStr($sFile,'.',0,-1)) <> 'bmp' Then SetError(2) Return -2 EndIf Select Case $iType = 1 RegWrite('HKCU\Control Panel\Desktop','TileWallpaper','reg_sz','1') RegWrite('HKCU\Control Panel\Desktop','WallpaperStyle','reg_sz','0') Case $iType = 2 RegWrite('HKCU\Control Panel\Desktop','TileWallpaper','reg_sz','0') RegWrite('HKCU\Control Panel\Desktop','WallpaperStyle','reg_sz','0') Case $iType = 3 RegWrite('HKCU\Control Panel\Desktop','TileWallpaper','reg_sz','0') RegWrite('HKCU\Control Panel\Desktop','WallpaperStyle','reg_sz','2') Case Else EndSelect RegWrite('HKCU\Control Panel\Desktop','Wallpaper','reg_sz',$sFile) DllCall("User32.dll","int","SystemParametersInfo","int",20,"int",0,"str",$sFile,"int",0) Return 0 EndFunc  
      The flow that I understand should be:
      1) Check what wallpaper is in use now. I can find the path to it by going to registry  key named "wallpaper" here :[HKEY_CURRENT_USER\Control Panel\Desktop]
      2) Create a file mspaint
      3) Create a label with its properties (size,color) in this file
      3) Save this file in some temporary directory
      4) Set a created file as a wallpaper using the above code
      5) When the script is closed restore the old wallpaper.
       
      So again, my question is how to create a .bmp file with label in it?
    • Ian_Mac
      By Ian_Mac
      Func dg_get_images() $x1=0 $y1=0 ;MsgBox(0,"start","start") do $result = _ImageSearch("C:\Users\Server\Desktop\my project\image.png",1,$x1,$y1,0) until $result = 1; if $result=1 Then MouseMove($x1,$y1,3) MouseClick("left", $x1,$y1, 1) WinWait("[Title:TightVNC File Transfer]", "", 10) EndIf  this code works when i search the image, but when i change the location of the desktop icon it can't find the desktop icon anymore.   i wanna try image search area. but i don't know how to use it because i cant understand the parameter for the image search area.  please help me how to solve it thank you in advance.
    • timmalos
      By timmalos
      Hey all.
      I'm trying to know when my user clicks on a Rect drawn via GDI+. Everything is almost working except I have a strange behaviour in the "order" clicks are fired.
      I created a simplified code to help :
      #include <GDIPlus.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <StaticConstants.au3> #include <WinAPI.au3> #include <Array.au3> Opt("GUIOnEventMode", 1) ;0=disabled, 1=OnEvent mode enabled _GDIPlus_Startup() Global $hGUI, $hGraphics Global $iWidth = 1024, $iHeight = 762 createGUI() draw() While 1 Sleep(10) WEnd Func createGUI() $hGUI = GUICreate("Current CasparCG Output", $iWidth,$iHeight) GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents") GUISetBkColor(0x000000) GUISetState(@SW_SHOW) $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) _GDIPlus_GraphicsSetSmoothingMode($hGraphics, $GDIP_SMOOTHINGMODE_HIGHQUALITY) ;sets the graphics object rendering quality (antialiasing) EndFunc ;==>Example Func draw() ;_WinAPI_draw($hGUI,"","",BitOR($RDW_ERASE,$RDW_INVALIDATE,$RDW_UPDATENOW)) _GDIPlus_GraphicsClear($hGraphics) $hFamily = _GDIPlus_FontFamilyCreate("Arial") $hFont = _GDIPlus_FontCreate($hFamily, 15, 1) $hPen = _GDIPlus_PenCreate(0xFFFEDCFF, 2) ;color format AARRGGBB (hex) $hFormat = _GDIPlus_StringFormatCreate() _GDIPlus_StringFormatSetAlign($hFormat, 1) _GDIPlus_StringFormatSetLineAlign($hFormat, 1) $hBrushString = _GDIPlus_BrushCreateSolid(0xFFFFFFFF) Local $hBrush = _GDIPlus_BrushCreateSolid(0xFFFF00FF) ;color format AARRGGBB (hex) For $i = 1 to 2 Local $x = 0.25 Local $y = 0.25 Local $w = 0.5 Local $h = 0.5 Local $title = "Layer "&$i If $x >= -1 And $x <= 1 Then $x *= $iWidth If $y >= -1 And $y <= 1 Then $y *= $iHeight If $w >= -1 And $w <= 1 Then $w *= $iWidth If $h >= -1 And $h <= 1 Then $h *= $iHeight $hItem = GUICtrlCreateLabel("", $x,$y,$w,$h) GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) GUICtrlSetOnEvent($hItem,"_gui_layer_clicked") ConsoleWrite("Created label with handle="&$hItem&" $i= " & $i&@CRLF) _GDIPlus_GraphicsFillRect($hGraphics, $x, $y, $w, $h,$hBrush) _GDIPlus_GraphicsDrawRect($hGraphics, $x, $y, $w, $h,$hPen) $tLayout = _GDIPlus_RectFCreate($x, $y, $w, $h) $aInfo = _GDIPlus_GraphicsMeasureString($hGraphics, $title, $hFont, $tLayout, $hFormat) _GDIPlus_GraphicsDrawStringEx($hGraphics, $title, $hFont, $aInfo[0], $hFormat, $hBrushString) Next _GDIPlus_BrushDispose($hBrush) _GDIPlus_PenDispose($hPen) _GDIPlus_FontDispose($hFont) _GDIPlus_StringFormatDispose($hFormat) _GDIPlus_FontFamilyDispose($hFamily) _GDIPlus_BrushDispose($hBrushString) Return 1 EndFunc Func _gui_layer_clicked() ConsoleWrite("Clicked on " & @GUI_CtrlId&@CRLF) EndFunc Func SpecialEvents() Select Case @GUI_CtrlId = $GUI_EVENT_CLOSE ; Clean up resources _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_Shutdown() Exit EndSelect EndFunc ;==>SpecialEvents What happens there :
      We have two rectangles, with the one labelled "2" is front and, the one labelled "1" in background. However when we click, the fired label is the one created first (in the background) and not the second one (in the front).
      Is it normal ?
      If yes, is there any way to change this order ? If I create another label after a first one on the same coords, I would the second one to be fired instead of the first one (This is a simplified code I can't just invert the label order creation easily)
       
      Thanks for your help
       
    • InunoTaishou
      By InunoTaishou
      Struggling a bit to get this GDI+ function converted to AutoIt.
      #include <GDIPlus.au3> _GDIPlus_Startup() Global $hImage = _GDIPlus_ImageLoadFromFile("F:\DCIM\Camera\20170515_111804.jpg") Global $tBufferSize = DllStructCreate("uint") Global $tProperties = DllStructCreate("uint") _GDIPlus_GetPropertySize($hImage, $tBufferSize, $tProperties) Global $tAllItems = DllStructCreate("struct;char[" & DllStructGetData($tBufferSize, 1) & "];endstruct") _GDIPlus_GetAllPropertyItems($hImage, $tBufferSize, $tProperties, $tPropertyItem) _GDIPlus_ImageDispose($hImage) _GDIPlus_Shutdown() Func _GDIPlus_GetAllPropertyItems(ByRef $hImage, Const $tTotalBufferSize, Const $tNumProperties, ByRef $tAllItems) If (Not IsDllStruct($tPropertyItem)) Then Return SetError(-1, 0, "") Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetAllPropertyItems", "hwnd", $hImage, "unit", DllStructGetData($tTotalBufferSize, 1), "uint", DllStructGetData($tNumProperties, 1), "ptr", DllStructGetPtr($tAllItems)) If (@error) Then Return SetError(@error, @extended, ConsoleWrite("@Error = " & @error & @LF)) If ($aResult[0]) Then Return SetError($aResult[0], @extended, "") Return $aResult[0] EndFunc ;==>_GDIPlus_GetAllPropertyItems Func _GDIPlus_GetPropertySize(Const ByRef $hImage, ByRef $tTotalBufferSize, ByRef $tNumProperties) If (Not IsDllStruct($tTotalBufferSize)) Then Return SetError(-1, 0, "") If (Not IsDllStruct($tNumProperties)) Then Return SetError(-2, 0, "") Local $aResult = DllCall($__g_hGDIPDll, "uint", "GdipGetPropertySize", "hwnd", $hImage, "uint_ptr", DllStructGetPtr($tTotalBufferSize), "uint_ptr", DllStructGetPtr($tNumProperties)) If (@error) Then Return SetError(@error, @extended, "") If ($aResult[0]) Then Return SetError($aResult[0], 0, "") Return $aResult[0] EndFunc ;==>_GDIPlus_GetPropertySize Got the GetPropertySize function to work, gives me the correct buffer size and the property count, but I cannot figure out how to get the struct for the all items.
      Function on MSDN:
      https://msdn.microsoft.com/en-us/library/windows/desktop/ms535372(v=vs.85).aspx
      Struct needed:
      PropertyItem class:
      https://msdn.microsoft.com/en-us/library/windows/desktop/ms534493(v=vs.85).aspx
      Found other topics about this function in other languages where they used a blank string as the buffer, so I tried using a char array, which doesn't work. Just cannot figure out how to create the struct buffer to hold the data.
    • UEZ
      By UEZ
      Since I disovered FreeBasic I decided to create a DLL to implement much faster image processing functionality to AutoIt.
      Following functions are implemented yet:
      _GDIPlus_BitmapApplyFilter_BWJJNDithering _GDIPlus_BitmapApplyFilter_Cartoon1 _GDIPlus_BitmapApplyFilter_ColorAccent _GDIPlus_BitmapApplyFilter_Convolution_AnotherBlur _GDIPlus_BitmapApplyFilter_Convolution_BoxBlur _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection1 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection2 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection3 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection4 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection5 _GDIPlus_BitmapApplyFilter_Convolution_EdgeDetection6 _GDIPlus_BitmapApplyFilter_Convolution_Emboss1 _GDIPlus_BitmapApplyFilter_Convolution_Emboss45Degree _GDIPlus_BitmapApplyFilter_Convolution_EmbossTopLeftBottomRight _GDIPlus_BitmapApplyFilter_Convolution_Gaussian3x3 _GDIPlus_BitmapApplyFilter_Convolution_Gaussian5x5_1 _GDIPlus_BitmapApplyFilter_Convolution_Gaussian5x5_2 _GDIPlus_BitmapApplyFilter_Convolution_GaussianBlur _GDIPlus_BitmapApplyFilter_Convolution_IntenseEmboss _GDIPlus_BitmapApplyFilter_Convolution_Kirsch _GDIPlus_BitmapApplyFilter_Convolution_Laplace1 _GDIPlus_BitmapApplyFilter_Convolution_Laplace2 _GDIPlus_BitmapApplyFilter_Convolution_Laplace3 _GDIPlus_BitmapApplyFilter_Convolution_LaplacianOfGaussian _GDIPlus_BitmapApplyFilter_Convolution_ManualMatrix _GDIPlus_BitmapApplyFilter_Convolution_MotionBlur _GDIPlus_BitmapApplyFilter_Convolution_Outline3x3 _GDIPlus_BitmapApplyFilter_Convolution_Prewitt _GDIPlus_BitmapApplyFilter_Convolution_Sharpen1 _GDIPlus_BitmapApplyFilter_Convolution_Sharpen2 _GDIPlus_BitmapApplyFilter_Convolution_Sobel _GDIPlus_BitmapApplyFilter_Convolution_SovelVsPrewitt _GDIPlus_BitmapApplyFilter_Convolution_TriangleBlur _GDIPlus_BitmapApplyFilter_Convolution_Unsharp _GDIPlus_BitmapApplyFilter_Convolution_Unsharp5x5 _GDIPlus_BitmapApplyFilter_Dilatation _GDIPlus_BitmapApplyFilter_DistortionBlur _GDIPlus_BitmapApplyFilter_Edges _GDIPlus_BitmapApplyFilter_Erosion _GDIPlus_BitmapApplyFilter_FishEye _GDIPlus_BitmapApplyFilter_Indexed _GDIPlus_BitmapApplyFilter_Jitter _GDIPlus_BitmapApplyFilter_Kuwahara _GDIPlus_BitmapApplyFilter_Linellism _GDIPlus_BitmapApplyFilter_Median _GDIPlus_BitmapApplyFilter_Median2 _GDIPlus_BitmapApplyFilter_OilPainting _GDIPlus_BitmapApplyFilter_PenSketch _GDIPlus_BitmapApplyFilter_PenSketch2 _GDIPlus_BitmapApplyFilter_Pixelate _GDIPlus_BitmapApplyFilter_Pointillism _GDIPlus_BitmapApplyFilter_RadialBlur _GDIPlus_BitmapApplyFilter_Raster _GDIPlus_BitmapApplyFilter_Swirl _GDIPlus_BitmapApplyFilter_SymmetricNearestNeighbour _GDIPlus_BitmapApplyFilter_TiltShift _GDIPlus_BitmapApplyFilter_TimeWarp _GDIPlus_BitmapApplyFilter_Wave _GDIPlus_BitmapApplyFilter_XRay  
      Since I am absolutely a newbie in FreeBasic, the DLL may contain errors.  Please report any bug.
       
      FreeBasic source code can be found here: https://pastebin.com/Lugp6rCR
       
      To do:
      add function headers with descriptions speed-up FB code -> partly done add more filters -> ongoing  
      Credits to:
      Jakub Szymanowski rdc Dewald Esterhuizen Santhosh G_  Christian Graus www.gutgames.com  
      Have fun.
       
      Download link: 
       
      You can compare the speed with AutoIt version:
      #AutoIt3Wrapper_Version=b #include <Array.au3> #include <GDIPlus.au3> Global $sFile = FileOpenDialog("Select an image", "", "Images (*.jpg;*.png;*.gif;*.bmp)") If @error Then Exit _GDIPlus_Startup() Global Const $STM_SETIMAGE = 0x0172 Global Const $hImage = _GDIPlus_ImageLoadFromFile($sFile) Global Const $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) Global Const $hGUI = GUICreate("GDI+ Image Filters", $iW * 2, $iH) Global $fProg = 0, $iEnd = $iW * $iH - 1 AdlibRegister("Progress", 490) Global $t = TimerInit() Global Const $hGDIBitmap = _GDIPlus_BitmapApplyFilter_Median($hImage, 4) ConsoleWrite(Round(TimerDiff($t) / 1000, 2) & " s / " & Round(TimerDiff($t) / 60000, 2) & " min" & @CRLF) Global Const $iPic = GUICtrlCreatePic("", 0, 0, $iW - 1, $iH - 1) Global Const $iPic_o = GUICtrlCreatePic("", $iW, 0, $iW - 1, $iH - 1) _WinAPI_DeleteObject(GUICtrlSendMsg($iPic, $STM_SETIMAGE, $IMAGE_BITMAP, $hGDIBitmap)) Global Const $hGDIBitmap2 = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) _WinAPI_DeleteObject(GUICtrlSendMsg($iPic_o, $STM_SETIMAGE, $IMAGE_BITMAP, $hGDIBitmap2)) GUISetState() AdlibUnRegister("Progress") ToolTip("") Do Until GUIGetMsg() = -3 _GDIPlus_ImageDispose($hImage) _WinAPI_DeleteObject($hGDIBitmap) _WinAPI_DeleteObject($hGDIBitmap2) _GDIPlus_Shutdown() Exit Func Progress() ToolTip(Int($fProg / $iEnd * 100) & " % / " & Round(TimerDiff($t) / 60000, 2) & " min", MouseGetPos(0) + 30, MouseGetPos(1) + 30) EndFunc #Region Symmetric Nearest Neighbour Func _GDIPlus_BitmapApplyFilter_SymmetricNearestNeighbour($hImage, $fRadius = 2, $bGDI = True) ;no alpha channel implemented yet Local Const $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) Local Const $hBitmap_Dest = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local Const $tBitmapData_Dest = _GDIPlus_BitmapLockBits($hBitmap_Dest, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMWRITE, $GDIP_PXF32ARGB) Local Const $iScan0_Dest = DllStructGetData($tBitmapData_Dest, "Scan0") Local Const $tPixel_Dest = DllStructCreate("int[" & $iW * $iH & "];", $iScan0_Dest) Local Const $tBitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local Const $iScan0 = DllStructGetData($tBitmapData, "Scan0") Local Const $tPixel = DllStructCreate("int[" & $iW * $iH & "];", $iScan0) Local $iRowOffset, $iX, $iY, $c, $k, $sumR, $sumG, $sumB, $iCount, $xx, $yy, $iR, $iG, $iB, $iR1, $iG1, $iB1, $iR2, $iG2, $iB2, $x, $y For $iY = 0 To $iH - 1 $iRowOffset = $iY * $iW For $iX = 0 To $iW - 1 $sumR = 0 $sumG = 0 $sumB = 0 $iCount = 0 $c = DllStructGetData($tPixel, 1, $iRowOffset + $iX) $iR = BitShift(BitAND(0x00FF0000, $c), 16) $iG = BitShift(BitAND(0x0000FF00, $c), 8) $iB = BitAND(0x000000FF, $c) For $yy = -$fRadius To $fRadius For $xx = -$fRadius To $fRadius $k = $iX + $xx $x = $k < 0 ? 0 : $k > $iW - 1 ? $iW - 1 : $k $k = $iY + $yy $y = $k < 0 ? 0 : $k > $iH - 1 ? $iH - 1 : $k $c = DllStructGetData($tPixel, 1, $y * $iW + $x) $iR1 = BitShift(BitAND(0x00FF0000, $c), 16) $iG1 = BitShift(BitAND(0x0000FF00, $c), 8) $iB1 = BitAND(0x000000FF, $c) $k = $iX - $xx $x = $k < 0 ? 0 : $k > $iW - 1 ? $iW - 1 : $k $k = ($iY - $yy) $y = $k < 0 ? 0 : $k > $iH - 1 ? $iH - 1 : $k $c = DllStructGetData($tPixel, 1, $y * $iW + $x) $iR2 = BitShift(BitAND(0x00FF0000, $c), 16) $iG2 = BitShift(BitAND(0x0000FF00, $c), 8) $iB2 = BitAND(0x000000FF, $c) If __DeltaE($iR, $iG, $iB, $iR1, $iG1, $iB1) < __DeltaE($iR, $iG, $iB, $iR2, $iG2, $iB2) Then $sumR += $iR1 $sumG += $iG1 $sumB += $iB1 Else $sumR += $iR2 $sumG += $iG2 $sumB += $iB2 EndIf $iCount += 1 Next Next DllStructSetData($tPixel_Dest, 1, 0xFF000000 + Int($sumR / $iCount) * 0x10000 + Int($sumG / $iCount) * 0x100 + Int($sumB / $iCount), $iRowOffset + $iX) $fProg += 1 Next Next _GDIPlus_BitmapUnlockBits($hImage, $tBitmapData) _GDIPlus_BitmapUnlockBits($hBitmap_Dest, $tBitmapData_Dest) _GDIPlus_ImageSaveToFile($hBitmap_Dest, @ScriptDir & "\Filter_SNN" & $fRadius & "_" & @YEAR & @MON & @MDAY & @MIN & @SEC & ".png") If $bGDI Then Local $hGDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_Dest) _GDIPlus_BitmapDispose($hBitmap_Dest) Return $hGDIBitmap EndIf Return $hBitmap_Dest EndFunc Func __DeltaE($iR1, $iG1, $iB1, $iR2, $iG2, $iB2) Return Sqrt(($iR1 - $iR2) * ($iR1 - $iR2) + ($iG1 - $iG2) * ($iG1 - $iG2) + ($iB1 - $iB2) * ($iB1 - $iB2)) EndFunc #EndRegion #Region Jitter Func _GDIPlus_BitmapApplyFilter_Jitter($hImage, $iAmount = 20, $bGDI = True) Local Const $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) Local Const $hBitmap_Dest = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local Const $tBitmapData_Dest = _GDIPlus_BitmapLockBits($hBitmap_Dest, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMWRITE, $GDIP_PXF32ARGB) Local Const $iScan0_Dest = DllStructGetData($tBitmapData_Dest, "Scan0") Local Const $tPixel_Dest = DllStructCreate("int[" & $iW * $iH & "];", $iScan0_Dest) Local Const $tBitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local Const $iScan0 = DllStructGetData($tBitmapData, "Scan0") Local Const $tPixel = DllStructCreate("int[" & $iW * $iH & "];", $iScan0) Local $iX, $iY, $iRowOffset, $fNX, $fNY For $iY = 0 To $iH - 1 $iRowOffset = $iY * $iW + 1 For $iX = 0 To $iW - 1 $fNX = $iX + Int((Random() - 0.5) * $iAmount) $fNX = $fNX < 1 ? 1 : $fNX > $iW - 1 ? $iW - 1 : $fNX $fNY = ($iY + Int((Random() - 0.5) * $iAmount)) $fNY = $fNY < 1 ? 1 : $fNY > $iH - 1 ? $iH - 1 : $fNY $fNY *= $iW DllStructSetData($tPixel_Dest, 1, DllStructGetData($tPixel, 1, $fNY + $fNX), $iRowOffset + $iX) $fProg += 1 Next Next _GDIPlus_BitmapUnlockBits($hImage, $tBitmapData) _GDIPlus_BitmapUnlockBits($hBitmap_Dest, $tBitmapData_Dest) _GDIPlus_ImageSaveToFile($hBitmap_Dest, @ScriptDir & "\Filter_Jitter" & $iAmount & "_" & @YEAR & @MON & @MDAY & @MIN & @SEC & ".png") If $bGDI Then Local $hGDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_Dest) _GDIPlus_BitmapDispose($hBitmap_Dest) Return $hGDIBitmap EndIf Return $hBitmap_Dest EndFunc #EndRegion #Region Median Func _GDIPlus_BitmapApplyFilter_Median($hImage, $fRadius = 3, $bGDI = True) Local Const $iW = _GDIPlus_ImageGetWidth($hImage), $iH = _GDIPlus_ImageGetHeight($hImage) Local Const $hBitmap_Dest = _GDIPlus_BitmapCreateFromScan0($iW, $iH) Local Const $tBitmapData_Dest = _GDIPlus_BitmapLockBits($hBitmap_Dest, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMWRITE, $GDIP_PXF32ARGB) Local Const $iScan0_Dest = DllStructGetData($tBitmapData_Dest, "Scan0") Local Const $tPixel_Dest = DllStructCreate("int[" & $iW * $iH & "];", $iScan0_Dest) Local Const $tBitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW - 1, $iH - 1, $GDIP_ILMREAD, $GDIP_PXF32ARGB) Local Const $iScan0 = DllStructGetData($tBitmapData, "Scan0") Local Const $tPixel = DllStructCreate("int[" & $iW * $iH & "];", $iScan0) Local $iX, $iY, $iRowOffset For $iY = 0 To $iH - 1 $iRowOffset = $iY * $iW + 1 For $iX = 0 To $iW - 1 DllStructSetData($tPixel_Dest, 1, __Median_Value($iX, $iY, $fRadius, $tPixel, $iW, $iH), $iRowOffset + $iX) $fProg += 1 Next Next _GDIPlus_BitmapUnlockBits($hImage, $tBitmapData) _GDIPlus_BitmapUnlockBits($hBitmap_Dest, $tBitmapData_Dest) _GDIPlus_ImageSaveToFile($hBitmap_Dest, @ScriptDir & "\Filter_Median" & $fRadius & "_" & @YEAR & @MON & @MDAY & @MIN & @SEC & ".png") If $bGDI Then Local $hGDIBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap_Dest) _GDIPlus_BitmapDispose($hBitmap_Dest) Return $hGDIBitmap EndIf Return $hBitmap_Dest EndFunc Func __Median_Value($iPosX, $iPosY, $fRadius, $tPixel, $iW, $iH) Local $iX, $iY, $aColors[1000], $iColors = 0, $iSize = $iW * $iH - 1, $iOff, $e For $iX = $iPosX - $fRadius To $iPosX + $fRadius For $iY = $iPosY - $fRadius To $iPosY + $fRadius $iOff = 1 + $iY * $iW + $iX $aColors[$iColors] = DllStructGetData($tPixel, 1, $iOff < 1 ? 1 : $iOff > $iSize ? $iSize : $iOff) $iColors += 1 Next Next ReDim $aColors[$iColors] ;~ _ArraySort($aColors, 0) $e = $iColors - 1 __ArrayQuickSort1D($aColors, 0, $e) Local $iMid = Floor($iColors / 2), $iMedian If BitAND($iColors, 1) Then $iMedian = Int($aColors[$iMid + 1]) Else $iMedian = Int(($aColors[$iMid] + $aColors[$iMid + 1]) / 2) EndIf Return $iMedian EndFunc #EndRegion