Jump to content

Clearing an image drawn with _GDIPlus_BitmapCreateFromFile()


coderusa
 Share

Recommended Posts

I'm playing around with some GDI+ (be easy, it's my first time...) 

I am not quite sure how to properly clear an image after it has been created. I can get the picture to display where I want it, but I cannot for the life of me figure out how to clear it. I've spent the last 4 hours searching and looking through example scripts, help file info and of course forum stuff. Nothing seems to properly explain (to me) how to clear the image while leaving everything else intact. I've tried various different methods, and they either close the script in error, clear the entire GUI (including buttons) to black, or (currently) just closes the GUI with no error messages.... 🤯

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

Global $hGUI = " "
Global $Button = " "
Global $hBitmap = " "
Global $hGraphic = " "

_Test()

While 1
   $GUIGetMsg = GUIGetMsg(1)
   If $GUIGetMsg[1] = $hGUI Then
      Switch $GUIGetMsg[0]
         Case 0
            ContinueLoop
         Case $GUI_EVENT_CLOSE
            Exit
         Case $Button
            _ClearImg()
            ContinueLoop
      EndSwitch
   EndIf
WEnd
Func _Test()
    $hGUI = GUICreate("GDI+", 400, 300, -1, -1, $WS_CAPTION+$WS_POPUP+$WS_EX_APPWINDOW)
    GUISetIcon("creator.ico", $hGUI)
    $Button = GUICtrlCreateButton("Clear", 5, 270, 80, 20) ;clear image and display next image
    GUISetState()
    _Draw("TestImage2.bmp")
 EndFunc
;Clear drawn image
Func _ClearImg()
   _GDIPlus_StartUp()
   $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBitmap)
   _GDIPlus_GraphicsClear($hBitmap)
   _GDIPlus_GraphicsDispose($hGraphic)
   _GDIPlus_ImageDispose($hBitmap)
   _GDIPlus_Shutdown()
EndFunc
 ;_Draw("filename")
Func _Draw($data)
    _GDIPlus_Startup()
    $hBitmap = _GDIPlus_BitmapCreateFromFile($data)
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    _GDIPlus_GraphicsDrawImage($hGraphic, $hBitmap, 5, 5)
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_Shutdown()
EndFunc

 

Link to comment
Share on other sites

Here is an example:

#include <GUIConstantsEx.au3>
#include <GDIPlus.au3>
#include <WindowsConstants.au3>
#include <WinAPISysWin.au3>

Global $hGUI = " "
Global $Button = " "
Global $hBitmap = " "
Global $hGraphic = " "

_Test()

While 1
   $GUIGetMsg = GUIGetMsg(1)
   If $GUIGetMsg[1] = $hGUI Then
      Switch $GUIGetMsg[0]
         Case 0
            ContinueLoop
         Case $GUI_EVENT_CLOSE
            Exit
         Case $Button
            _ClearImg()
            ContinueLoop
      EndSwitch
   EndIf
WEnd

Func _Test()
    $hGUI = GUICreate("GDI+", 400, 300, -1, -1, $WS_CAPTION+$WS_POPUP+$WS_EX_APPWINDOW)
    GUISetIcon("creator.ico", $hGUI)
    $Button = GUICtrlCreateButton("Clear", 5, 270, 80, 20) ;clear image and display next image
    GUISetState()
    _Draw("TestImage2.bmp")
EndFunc

;Clear drawn image
Func _ClearImg()
    Local Const $tagRECT = "struct; long Left;long Top;long Right;long Bottom; endstruct"
    Local $tRect = DllStructCreate($tagRECT)
    With $tRect
        .Left = 5
        .Top = 5
        .Right = 5 + 390    ; Right = Left + Width
        .Bottom = 5 + 250   ; Bottom = Top + Height
    EndWith
   _WinAPI_InvalidateRect($hGUI, $tRect)
EndFunc

 ;_Draw("filename")
Func _Draw($data)
    _GDIPlus_Startup()
    $hBitmap = _GDIPlus_BitmapCreateFromFile($data)
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($hGUI)
    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hBitmap, 5, 5, 390, 250) ; Width: 390, Height: 250
    _GDIPlus_GraphicsDispose($hGraphic)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_Shutdown()
EndFunc

I modified in _Draw() function _GDIPlus_GraphicsDrawImage() with _GDIPlus_GraphicsDrawImageRect() because I don't know your sample picture size and I wanted to draw my sample at specific location.

When the words fail... music speaks.

Link to comment
Share on other sites

Thank you Andreik, that actually helps me a lot. I can read descriptions and stuff but to really get a hold of it I need "hands on" and the more examples I can find the better. Especially smaller snippets like these, some of the larger GDI examples, at this point, confuse me in my GDI+ n00bness 😆

 

This morning, with some "fresh eyes" I combed through the forums again and found a example written by UEZ that also helps.

;Example by UEZ
#include <GDIPlus.au3>
#include <GUIConstantsEx.au3>

_GDIPlus_Startup()
Global $hGUI = GUICreate("", 600, 400)
GUISetBkColor(0xF0F0F0, $hGUI)
Global $iBtn = GUICtrlCreateButton("Display", 500, 300, 50, 50)
GUISetState()

$hCanvas = _GDIPlus_GraphicsCreateFromHWND($hGUI)
$hBitmap = _GDIPlus_BitmapCreateFromGraphics(193, 184, $hCanvas) ;size of the torus.png image
$hGfx = _GDIPlus_ImageGetGraphicsContext($hBitmap)

$hImage1 = _GDIPlus_ImageLoadFromFile("c:\Program Files (x86)\AutoIt3\Examples\GUI\merlin.gif") ;size is 68x71
$hImage2 = _GDIPlus_ImageLoadFromFile("c:\Program Files (x86)\AutoIt3\Examples\GUI\Torus.png") ;size is 193x184
_GDIPlus_GraphicsDrawImageRect($hGfx, $hImage1, 0, 0, 68, 71)
_GDIPlus_GraphicsDrawImageRect($hCanvas, $hBitmap, 0, 0, 193, 184)

Do
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            ExitLoop
        Case $iBtn
            _GDIPlus_GraphicsClear($hGfx, 0xFFF0F0F0)
            _GDIPlus_GraphicsDrawImageRect($hGfx, $hImage2, 0, 0, 193, 184)
            _GDIPlus_GraphicsDrawImageRect($hCanvas, $hBitmap, 0, 0, 193, 184)
    EndSwitch
Until False

_GDIPlus_GraphicsDispose($hCanvas)
_GDIPlus_GraphicsDispose($hGfx)
_GDIPlus_ImageDispose($hImage1)
_GDIPlus_ImageDispose($hImage2)
_GDIPlus_ImageDispose($hBitmap)
_GDIPlus_Shutdown()
GUIDelete()

 

Edited by coderusa
Link to comment
Share on other sites

You can also have a Picture control and you can use GDI+ to draw things in the control. In this way you don't have to care about redrawing when a window overlaps your graphics.

#include <GDIPlus.au3>

Global $hGUI, $idPicture
Global Const $STM_SETIMAGE = 0x0172

$hGUI = GUICreate("GDI+ Test", 400, 450)
$idPicture = GUICtrlCreatePic('', 5, 5, 390, 390, 0x1000) ; SS_SUNKEN
$idDraw = GUICtrlCreateButton('Draw', 50, 410, 100, 30)
$idClear = GUICtrlCreateButton('Clear', 250, 410, 100, 30)
GUISetState()

While True
    Switch GUIGetMsg()
        Case -3 ; GUI_EVENT_CLOSE
            Exit
        Case $idDraw
            DrawImage()
        Case $idClear
            ClearImage()
    EndSwitch
WEnd

Func DrawImage()
    ; Create a sample image
    _GDIPlus_Startup()
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0(390, 390)
    Local $hContext = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    Local $hBrush = _GDIPlus_BrushCreateSolid(0xFFFCA311)
    _GDIPlus_GraphicsClear($hContext, 0xFFCCD5AE)
    _GDIPlus_GraphicsFillEllipse($hContext, 100, 100, 50, 75, $hBrush)
    _GDIPlus_BrushSetSolidColor($hBrush, 0xFF264653)
    _GDIPlus_GraphicsFillRect($hContext, 220, 230, 80, 115, $hBrush)

    ; Draw to picture control
    Local $hHBITMAP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
    _WinAPI_DeleteObject(GUICtrlSendMsg($idPicture, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBITMAP))
    _WinAPI_DeleteObject($hHBITMAP)

    ; Dispose resources
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hContext)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_Shutdown()
EndFunc

Func ClearImage()
    _WinAPI_DeleteObject(GUICtrlSendMsg($idPicture, $STM_SETIMAGE, $IMAGE_BITMAP, 0))
    ; or GUICtrlSetImage($idClear, '')
EndFunc

 

Edited by Andreik

When the words fail... music speaks.

Link to comment
Share on other sites

2 minutes ago, Andreik said:

You can also have a Picture control and you can use GDI+ to draw things in the control. In these way you don't have to care about redrawing when a window overlaps your graphics.

#include <GDIPlus.au3>

Global $hGUI, $idPicture
Global Const $STM_SETIMAGE = 0x0172

$hGUI = GUICreate("GDI+ Test", 400, 450)
$idPicture = GUICtrlCreatePic('', 5, 5, 390, 390, 0x1000) ; SS_SUNKEN
$idDraw = GUICtrlCreateButton('Draw', 50, 410, 100, 30)
$idClear = GUICtrlCreateButton('Clear', 250, 410, 100, 30)
GUISetState()

While True
    Switch GUIGetMsg()
        Case -3 ; GUI_EVENT_CLOSE
            Exit
        Case $idDraw
            DrawImage()
        Case $idClear
            ClearImage()
    EndSwitch
WEnd

Func DrawImage()
    ; Create a sample image
    _GDIPlus_Startup()
    Local $hBitmap = _GDIPlus_BitmapCreateFromScan0(390, 390)
    Local $hContext = _GDIPlus_ImageGetGraphicsContext($hBitmap)
    Local $hBrush = _GDIPlus_BrushCreateSolid(0xFFFCA311)
    _GDIPlus_GraphicsClear($hContext, 0xFFCCD5AE)
    _GDIPlus_GraphicsFillEllipse($hContext, 100, 100, 50, 75, $hBrush)
    _GDIPlus_BrushSetSolidColor($hBrush, 0xFF264653)
    _GDIPlus_GraphicsFillRect($hContext, 220, 230, 80, 115, $hBrush)

    ; Draw to picture control
    Local $hHBITMAP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap)
    _WinAPI_DeleteObject(GUICtrlSendMsg($idPicture, $STM_SETIMAGE, $IMAGE_BITMAP, $hHBITMAP))
    _WinAPI_DeleteObject($hHBITMAP)

    ; Dispose resources
    _GDIPlus_BrushDispose($hBrush)
    _GDIPlus_GraphicsDispose($hContext)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_Shutdown()
EndFunc

Func ClearImage()
    _WinAPI_DeleteObject(GUICtrlSendMsg($idPicture, $STM_SETIMAGE, $IMAGE_BITMAP, 0))
    ; or GUICtrlSetImage($idClear, '')
EndFunc

 

This is also an excellent example. Thank you again. I will play around with this especially because I had started reading about using picture controls. 

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

  • Recently Browsing   0 members

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