Jump to content

Resizing an image using GDIPlus


Recommended Posts

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

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

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