Jump to content

Image Editor using GDI+


InunoTaishou
 Share

Recommended Posts

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
Link to comment
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
 Share

×
×
  • Create New...