Jump to content
Sign in to follow this  
hypersonic

Resizing an image using GDIPlus

Recommended Posts

hypersonic

Hi All,

Part of my program grabs a screenshot, resizes it down, then saves it to disk.

The function below gets called repeatedly every 4 seconds. It works fine, and the jpg image is written to disk(to a file server via \\server\share\), but i'm finding that after a couple of minutes, an error message is displayed and the whole autoit script terminates. (see attached).

Am I doing this right? It's my first time working with GDIplus / these UDF's. Even if I can suppress these error messages and stop the script from terminating, that would be fine.

Funnily enough it seems to be stable on my server 2003 dev box, but not on my clean windows xp box (?). Perhaps since the 2003 box is closer to the file server, the write completes before it trys again, whereas the xp box doesnt complete writing the file, and it tries again when the file is open? or something?)

Any ideas/suggestions would be much appreciated.

#include <ScreenCapture.au3>
_ScreenCapture_SetJPGQuality(30)
Dim $settingsFilePath = "\\server\share\" ;w/ trailing slash

;Saves a screenshot of the screen to disk... 
;Resizes the image to 1/4th its original size
Func SaveScreenPreview()
    Dim $oldImage
    Dim $GC
    Dim $newBmp
    Dim $newGC
    Dim $newW = @DesktopWidth / 4
    Dim $newH = @DesktopHeight / 4
    Dim $newFileName = $settingsFilePath & @ComputerName & ".jpg"
    
    
    ;Init GDIPlus
    _GDIPlus_Startup()

    ;Get screenshot
    $oldImage = _GDIPlus_BitmapCreateFromHBITMAP(_ScreenCapture_Capture())
    
    ;Create New image
    $GC = _GDIPlus_ImageGetGraphicsContext($oldImage)
    $newBmp = _GDIPlus_BitmapCreateFromGraphics($newW,$newH,$GC)
    $newGC = _GDIPlus_ImageGetGraphicsContext($newBmp)

    ;Draw
    _GDIPlus_GraphicsDrawImageRect($newGC,$oldImage,0,0,$newW,$newH)
    _GDIPlus_ImageSaveToFile($newBmp,$newFileName)

    ;Cleanup
    _GDIPlus_GraphicsDispose($GC)
    _GDIPlus_GraphicsDispose($newGC)
    _GDIPlus_BitmapDispose($newBmp)
    _GDIPlus_ImageDispose($oldImage)
    
    ;Shutdown GDIPlus
    _GDIPlus_Shutdown()
    
EndFunc

post-53509-12553161509563_thumb.png

Edited by hypersonic

Share this post


Link to post
Share on other sites
smashly

Hi,

probably crashing due to your not deleting the screen capture HBITMAP..

eg: $oldImage = _GDIPlus_BitmapCreateFromHBITMAP(_ScreenCapture_Capture())

So after few times of calling your function the scripts exceeds it's memory limit and crash..

Also the _ScreenCapture_SetJPGQuality(30) has no meaning in your script as your not using the Screen Capture function to save the capture to a file.

I just tried your function with deleting the screen capture HBITMAP and ran the function in a loop until I hit the Esc key on my keyboard..

No crashes at all.

#include <ScreenCapture.au3>
#include <GDIPlus.au3>
#include <Misc.au3>

Global $OutPath = @ScriptDir & "\"

Do
    _SaveScreenPreview()
    Sleep(500)
Until _IsPressed("1B") ;Esc to quit

Func _SaveScreenPreview()
    Local $i = 1
    Local $OutFile = $OutPath & StringFormat("%03d", $i) & "_" & @ComputerName & ".jpg"
    Local $hBitmap, $hImage1, $hGraphic, $hImage2, $newW = @DesktopWidth / 4, $newH = @DesktopHeight / 4

    $hBitmap = _ScreenCapture_Capture()
    _GDIPlus_Startup()
    $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
    _WinAPI_DeleteObject($hBitmap) ;Get rid of the original screen capture. (this was probably why you were crashing.)
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage1)
    $hImage2 = _GDIPlus_BitmapCreateFromGraphics($newW, $newH, $hGraphic)
    _GDIPlus_GraphicsDispose($hGraphic) ;Get rid of the $hGraphic
    $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage2)
    _GDIPlus_GraphicsDrawImageRect($hGraphic, $hImage1, 0, 0, $newW, $newH)
    _GDIPlus_GraphicsDispose($hGraphic) ;Get rid of the $hGraphic again.
    _GDIPlus_ImageDispose($hImage1) ;Get rid of the 1st $hImage

    ;Generate a file name with a number, I didn't want to overwrite an existing picture.
    While FileExists($OutFile)
        $i += 1
        $OutFile = @ScriptDir & "\" & StringFormat("%03d", $i) & "_" & @ComputerName & ".jpg"
    Wend

    _GDIPlus_ImageSaveToFile($hImage2, $OutFile)
    _GDIPlus_ImageDispose($hImage2) ;Dispose of the 2nd $hImage
    _GDIPlus_Shutdown()
EndFunc

Cheers

Edited by smashly

Share this post


Link to post
Share on other sites
hypersonic

OK i'll try that and let you know how I go :)

Share this post


Link to post
Share on other sites
Yashied

Another way.

#Include <GDIPlus.au3>
#Include <ScreenCapture.au3>

$hBitmap = _ScreenCapture_Capture()
_GDIPlus_Startup()
$hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
_WinAPI_DeleteObject($hBitmap)
$hThumb = _GDIPlus_GetImageThumbnail($hImage, _GDIPlus_ImageGetWidth($hImage) / 4, _GDIPlus_ImageGetHeight($hImage) / 4)
_GDIPlus_ImageDispose($hImage)
_GDIPlus_ImageSaveToFile($hThumb, 'screenshort.jpg')
_GDIPlus_ImageDispose($hThumb)
_GDIPlus_Shutdown()

Func _GDIPlus_GetImageThumbnail($hImage, $iWidth, $iHeight)

    Local $Ret = DllCall($ghGDIPDll, 'int', 'GdipGetImageThumbnail', 'ptr', $hImage, 'int', $iWidth, 'int', $iHeight, 'ptr*', 0, 'ptr', 0, 'ptr', 0)

    If (@error) Or ($Ret[0]) Then
        Return SetError(1, 0, 0)
    EndIf
    Return $Ret[4]
EndFunc   ;==>_GDIPlus_GetImageThumbnail

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  

×