Jump to content

GDIPlus & a magnifying glass attempt. How to free memory?


Gianni
 Share

Go to solution Solved by Danyfirex,

Recommended Posts

This lens snippet (assembled using other snippets from the forum and from the help file)  makes memory usage grow linearly, and never released till closed.
could someone tell me what should I change to make it do a regular use of memory?
thanks

This listing is debugged (Thanks to Danyfirex)

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

Global Const $iWidth = 400, $iHeight = 200 ; lens dimensions
Global $Magnify = 2 ; zoom factor
Global $CapureCursor = False ; If True the cursor will be captured with the image
;
Global $g_hGUI, $g_hGfxCtxt, $g_hBitmap, $g_hGraphics
Global $Mouse[2], $CaptureX = $iWidth / ($Magnify * 2), $CaptureY = $iHeight / ($Magnify * 2)

Example()

Func Example()
    AutoItSetOption("GUIOnEventMode", 1)
    _GDIPlus_Startup() ;initialize GDI+

    $g_hGUI = GUICreate("Magnifier", $iWidth, $iHeight, -1, -1, $DS_MODALFRAME, $WS_EX_TOPMOST)
    GUISetState(@SW_SHOW)

    ;create buffered graphics frame set for smoother gfx object movements
    $g_hGraphics = _GDIPlus_GraphicsCreateFromHWND($g_hGUI) ;create a graphics object from a window handle
    $g_hBitmap = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $g_hGraphics)
    $g_hGfxCtxt = _GDIPlus_ImageGetGraphicsContext($g_hBitmap)

    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")

    local $g_hBitmap2 = 0
    Do
        $g_hBitmap2 = SnapShot()
        _GDIPlus_GraphicsClear($g_hGfxCtxt, 0xFF000000) ;clear bitmap for repaint
        _GDIPlus_GraphicsDrawImage($g_hGfxCtxt, $g_hBitmap2, 0, 0) ;draw bitmap to backbuffer
        _GDIPlus_GraphicsDrawImageRect($g_hGraphics, $g_hBitmap, 0, 0, $iWidth, $iHeight) ;copy drawn bitmap to graphics handle (GUI)
        _GDIPlus_BitmapDispose($g_hBitmap2)

    Until Not Sleep(10) ;sleep 10 ms to avoid high cpu usage


EndFunc   ;==>Example

Func SnapShot()
    $Mouse = MouseGetPos()
    ; Capture region (centered on mouse position; dimensions based on the $CaptureX and $CaptureY variables)
    $hHBITMAP = _ScreenCapture_Capture("", $Mouse[0] - $CaptureX, $Mouse[1] - $CaptureY, $Mouse[0] + $CaptureX, $Mouse[1] + $CaptureY, $CapureCursor)

    ; http://www.autoitscript.com/forum/topic/130856-enlargezoom-image-after-screencapture/?p=910694

    ; Create a Bitmap object from the bitmap handle
    $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hHBITMAP)

    ; Dispose of the original capture since we now have a bitmap image we can use with GDIPlus.
    _WinAPI_DeleteObject($hHBITMAP)

    ; Get the graphics context of the bitmap image.
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)

    ; Creates a new Bitmap object based on the Graphic object with a new width and height.
    $hHBITMAP = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphic)

    ; Dispose of the Graphic context now we have a newly sized bitmap image as a canvas.
    _GDIPlus_GraphicsDispose($hGraphic)

    ; Get the graphics context of the newly sized bitmap image
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hHBITMAP)

    ; Draw the original image onto the newly sized image.
    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hImage, 0, 0, $iWidth, $iHeight) ; 200, 200)

    ; Dispose of the Graphic context now we have drawn the original image to it.
    _GDIPlus_GraphicsDispose($hGraphic)

    ; Dispose of the original image.
    _GDIPlus_ImageDispose($hImage)

    Return($hHBITMAP)
EndFunc   ;==>SnapShot

Func _Exit()
    ;cleanup GDI+ resources
    _GDIPlus_GraphicsDispose($g_hGfxCtxt)
    _GDIPlus_GraphicsDispose($g_hGraphics)
    _GDIPlus_BitmapDispose($g_hBitmap)
    _GDIPlus_Shutdown()
    GUIDelete($g_hGUI)
    Exit
EndFunc   ;==>_Exit

Buggy version is in spoiler

 

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

Global Const $iWidth = 400, $iHeight = 200 ; lens dimensions
Global $Magnify = 2 ; zoom factor
Global $CapureCursor = False ; If True the cursor will be captured with the image
;
Global $g_hGUI, $g_hGfxCtxt, $g_hBitmap, $g_hGraphics
Global $Mouse[2], $CaptureX = $iWidth / ($Magnify * 2), $CaptureY = $iHeight / ($Magnify * 2)

Example()

Func Example()
    AutoItSetOption("GUIOnEventMode", 1)
    _GDIPlus_Startup() ;initialize GDI+

    $g_hGUI = GUICreate("Magnifier", $iWidth, $iHeight, -1, -1, $DS_MODALFRAME,  $WS_EX_TOPMOST)
    GUISetState(@SW_SHOW)

    ;create buffered graphics frame set for smoother gfx object movements
    $g_hGraphics = _GDIPlus_GraphicsCreateFromHWND($g_hGUI) ;create a graphics object from a window handle
    $g_hBitmap = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $g_hGraphics)
    $g_hGfxCtxt = _GDIPlus_ImageGetGraphicsContext($g_hBitmap)

    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")

    Do
        _GDIPlus_GraphicsClear($g_hGfxCtxt, 0xFF000000) ;clear bitmap for repaint
        _GDIPlus_GraphicsDrawImage($g_hGfxCtxt, SnapShot(), 0, 0) ;draw bitmap to backbuffer
        _GDIPlus_GraphicsDrawImageRect($g_hGraphics, $g_hBitmap, 0, 0, $iWidth, $iHeight) ;copy drawn bitmap to graphics handle (GUI)
    Until Not Sleep(10) ;sleep 10 ms to avoid high cpu usage
EndFunc   ;==>Example

Func SnapShot()
    $Mouse = MouseGetPos()
    ; Capture region (centered on mouse position; dimensions based on the $CaptureX and $CaptureY variables)
    $hHBITMAP = _ScreenCapture_Capture("", $Mouse[0] - $CaptureX, $Mouse[1] - $CaptureY, $Mouse[0] + $CaptureX, $Mouse[1] + $CaptureY, $CapureCursor)

    ; http://www.autoitscript.com/forum/topic/130856-enlargezoom-image-after-screencapture/?p=910694

    ; Create a Bitmap object from the bitmap handle
    $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hHBITMAP)

    ; Dispose of the original capture since we now have a bitmap image we can use with GDIPlus.
    _WinAPI_DeleteObject($hHBITMAP)

    ; Get the graphics context of the bitmap image.
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage)

    ; Creates a new Bitmap object based on the Graphic object with a new width and height.
    $hHBITMAP = _GDIPlus_BitmapCreateFromGraphics($iWidth, $iHeight, $hGraphic)

    ; Dispose of the Graphic context now we have a newly sized bitmap image as a canvas.
    _GDIPlus_GraphicsDispose($hGraphic)

    ; Get the graphics context of the newly sized bitmap image
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hHBITMAP)

    ; Draw the original image onto the newly sized image.
    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hImage, 0, 0, $iWidth, $iHeight) ; 200, 200)

    ; Dispose of the Graphic context now we have drawn the original image to it.
    _GDIPlus_GraphicsDispose($hGraphic)

    ; Dispose of the original image.
     _GDIPlus_ImageDispose($hImage)

    Return ($hHBITMAP)
EndFunc   ;==>Shot

Func _Exit()
    ;cleanup GDI+ resources
    _GDIPlus_GraphicsDispose($g_hGfxCtxt)
    _GDIPlus_GraphicsDispose($g_hGraphics)
    _GDIPlus_BitmapDispose($g_hBitmap)
    _GDIPlus_Shutdown()
    GUIDelete($g_hGUI)
    Exit
EndFunc   ;==>_Exit

 

 

Edited by Chimp

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

  • Solution

Edit. I did nto read well.

Sleep 30.

Edit 2

Look:

Local $g_hBitmap2=0
    Do
         $g_hBitmap2= SnapShot()
        _GDIPlus_GraphicsClear($g_hGfxCtxt, 0xFF000000) ;clear bitmap for repaint
        _GDIPlus_GraphicsDrawImage($g_hGfxCtxt, $g_hBitmap2, 0, 0) ;draw bitmap to backbuffer
        _GDIPlus_GraphicsDrawImageRect($g_hGraphics, $g_hBitmap, 0, 0, $iWidth, $iHeight) ;copy drawn bitmap to graphics handle (GUI)
   _GDIPlus_BitmapDispose($g_hBitmap2)

    Until Not Sleep(10) ;sleep 10 ms to avoid high cpu usage

saludos

Edited by Danyfirex
Link to comment
Share on other sites

Thanks Danyflex,

if I increase the sleeping time to 30 or even more, the memory usage grows slowly (of course), but it grows anyway.

edit:

I think I should release some resource somewhere, but don't know what

Edited by Chimp

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

I changed my answer. look again  >here

Saludos

Edited by Danyfirex
Link to comment
Share on other sites

You're welcome.

To keep the forum cleaner. you can mark the topic as answered.

Saludos

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...