Jump to content

GDIPlus Change Quality + Scale


Recommended Posts

EDIT: Since there hasn't been a reply, I assume this functionality is unavailable in current release... or the thread become TLDR. Figured I should do the same as I did for uploading a form without IE, and find a command-line tool. I'm going to use G'MIC. I looked at imagemagick but it had an entire GUI thing and too many files to include. I just need to resize and change the quality :mellow:

I need two functions that should be simple, and I'm very surprised I don't see them in the help file. I just need this capability in it's most basic form, the quality function is very important, the scale is not but could add many features to my program.

Maybe I have overlooked these, but if I knew enough to make these functions here is how I would use them:

$hBMP = _ScreenCapture_Capture("")
$hBMP = _GDIPlus_ImageResize($hBMP, 1024, 768, True) ;True would be for preserving aspect ratio, somehow
_ScreenCapture_SaveImageQuality($hBMP, @scriptdir & "\file.jpg", 95) ; 95 being the image quality

Now these might exist with a different name, but I don't see them.

I used this function in the past but it's old code, there are a few errors when I try to compile and when I fix the errors the include file starts throwing more errors...

Func __ScreenCapture_SaveImage($sFileName, $hBitmap, $fFreeBmp, $iQuality)
    Local $hClone, $sCLSID, $tData, $sExt, $hImage, $pParams, $tParams, $iResult, $iX, $iY

    If @error Then Return SetError(-1, -1, False)

    $sExt = StringUpper(_GDIPlus_ExtractFileExt($sFileName))
    $sCLSID = _GDIPlus_EncodersGetCLSID($sExt)
    If $sCLSID = "" Then Return SetError(-2, -2, False)
    $hImage = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)
    If @error Then Return SetError(-3, -3, False)

    Switch $sExt
        Case "BMP"
            $iX = _GDIPlus_ImageGetWidth($hImage)
            $iY = _GDIPlus_ImageGetHeight($hImage)
            $hClone = _GDIPlus_BitmapCloneArea($hImage, 0, 0, $iX, $iY, $giBMPFormat)
            $hImage = $hClone
        Case "JPG", "JPEG"
            $tParams = _GDIPlus_ParamInit(1)
            $tData = DllStructCreate("int Quality")
            DllStructSetData($tData, "Quality", $iQuality)
            _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, DllStructGetPtr($tData))
        Case "TIF", "TIFF"
            $tParams = _GDIPlus_ParamInit(2)
            $tData = DllStructCreate("int ColorDepth;int Compression")
            DllStructSetData($tData, "ColorDepth", $giTIFColorDepth)
            DllStructSetData($tData, "Compression", $giTIFCompression)
            _GDIPlus_ParamAdd($tParams, $GDIP_EPGCOLORDEPTH, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "ColorDepth"))
            _GDIPlus_ParamAdd($tParams, $GDIP_EPGCOMPRESSION, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "Compression"))
    If IsDllStruct($tParams) Then $pParams = DllStructGetPtr($tParams)

    $iResult = _GDIPlus_ImageSaveToFileEx($hImage, $sFileName, $sCLSID, $pParams)
    If $fFreeBmp Then _WinAPI_DeleteObject($hBitmap)

    Return SetError($iResult = False, 0, $iResult = True)

Trying another answer but keep getting the error Autoit3.exe has encountered an error... Is there something wrong with this code? No errors if I just save it as a jpg, only when I add params.

$f = @scriptdir & "\file.jpg"
$q = 75
$hBMP = _ScreenCapture_Capture("")

$TParam = _GDIPlus_ParamInit(1)

$Datas = DllStructCreate("int Quality")
DllStructSetData($Datas, "Quality", $q)
_GDIPlus_ParamAdd($TParam, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, DllStructGetPtr($Datas))

$clsid = _GDIPlus_EncodersGetCLSID("JPG")

_GDIPlus_ImageSaveToFileEx($hBmp, $f, $clsid, DllStructGetPtr($TParam))
Edited by Rad
Link to comment
Share on other sites

Here a fast hack from the help file!

;fast hack by UEZ
#include <GuiConstantsEx.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>

Opt('MustDeclareVars', 1)


Func _Main()
    Local $hGUI1, $hGUI2, $hGUI3, $hImage, $hGraphic1, $hGraphic2, $hGraphic3, $sCLSID
    Local $bitmap1, $bitmap2, $bitmap3, $image1, $image2, $image3
    Local $tData, $tParams, $pParams, $pData

    ; Capture top left corner of the screen
    _ScreenCapture_Capture (@MyDocumentsDir & "\GDIPlus_Image.jpg", 0, 0, 400, 300)

    ; Create a GUI for the original image
    $hGUI1 = GUICreate("Original", 400, 300, 0, 0)

    ; Create a GUI for the zoomed image
    $hGUI2 = GUICreate("Scaled Up", 800, 600, 0, 350)

    ; Create a GUI for the scaled down image
    $hGUI3 = GUICreate("Scaled Down", 200, 150, 820, 400)

    ; Initialize GDI+ library and load image
    _GDIPlus_Startup ()
    $hImage = _GDIPlus_ImageLoadFromFile (@MyDocumentsDir & "\GDIPlus_Image.jpg")

    $sCLSID = _GDIPlus_EncodersGetCLSID ("JPG")

    ; Draw original image
    $hGraphic1 = _GDIPlus_GraphicsCreateFromHWND ($hGUI1)
    $bitmap1 = _GDIPlus_BitmapCreateFromGraphics(400, 300, $hGraphic1)
    $image1 = _GDIPlus_ImageGetGraphicsContext($bitmap1)
    _GDIPlus_GraphicsDrawImageRect($image1, $hImage, 0, 0, 400, 300)
    _GDIPlus_GraphicsDrawImageRect($hGraphic1, $bitmap1, 0, 0, 400, 300)
    _GDIPlus_ImageSaveToFileEx($bitmap1, @ScriptDir & "\GDIPlus_Image1.jpg", $sCLSID)

    ; Draw 2x scaled up image and save with lower jpg quality
    $hGraphic2 = _GDIPlus_GraphicsCreateFromHWND ($hGUI2)
    $bitmap2 = _GDIPlus_BitmapCreateFromGraphics(800, 600, $hGraphic2)
    $image2 = _GDIPlus_ImageGetGraphicsContext($bitmap2)
    _GDIPlus_GraphicsDrawImageRectRect ($image2, $hImage, 0, 0, 400, 300, 0, 0, 800, 600)
    _GDIPlus_GraphicsDrawImageRect($hGraphic2, $bitmap2, 0, 0, 800, 600)
    $tParams = _GDIPlus_ParamInit (1)
    $tData = DllStructCreate("int Quality")
    DllStructSetData($tData, "Quality", 10) ;quality 0-100
    $pData = DllStructGetPtr($tData)
    _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData)
    $pParams = DllStructGetPtr($tParams)
    _GDIPlus_ImageSaveToFileEx($bitmap2, @ScriptDir & "\GDIPlus_Image2.jpg", $sCLSID, $pParams)
    $tData = 0

    ; Draw 2x scaled down image
    $hGraphic3 = _GDIPlus_GraphicsCreateFromHWND ($hGUI3)
    $bitmap3 = _GDIPlus_BitmapCreateFromGraphics(200, 150, $hGraphic3)
    $image3 = _GDIPlus_ImageGetGraphicsContext($bitmap3)
    _GDIPlus_GraphicsDrawImageRectRect ($image3, $hImage, 0, 0, 400, 300, 0, 0, 200, 150)
        _GDIPlus_GraphicsDrawImageRect($hGraphic3, $bitmap3, 0, 0, 200, 150)
    _GDIPlus_ImageSaveToFileEx($bitmap3, @ScriptDir & "\GDIPlus_Image3.jpg", $sCLSID)

    ; Release resources
    _GDIPlus_GraphicsDispose ($hGraphic1)
    _GDIPlus_GraphicsDispose ($hGraphic2)
    _GDIPlus_GraphicsDispose ($hGraphic3)
    _GDIPlus_ImageDispose ($hImage)
    _GDIPlus_Shutdown ()

    ; Clean up screen shot file
    FileDelete(@MyDocumentsDir & "\GDIPlus_Image.jpg")

    ; Loop until user exits
    Until GUIGetMsg() = $GUI_EVENT_CLOSE


EndFunc ;==>_Main

I hope this is what you asked! If yes, then just create a function where you can do a batch scale of images...:mellow:


Edited by UEZ

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to comment
Share on other sites

Thanks for the reply, that seems to work and I am trying to fiddle with it. I don't understand why there is a need for graphics and also hbitmaps...


Got it to work best using this function, haven't implemented the ability to change width and height yet but you should be able to figure it out with the $h and $w variables. Probably not an efficient way to do it, but it's actually a lot faster than the command line utility.

Will tweak with it some more. I really think there should be GDI functions to just change the width height and quality. :mellow:

func image_quality($file, $quality, $name, $output)
    $hGUI3 = GUICreate("Scaled Down", 200, 150)

    _GDIPlus_Startup ()
    $hImage = _GDIPlus_ImageLoadFromFile ($name)
    $h = _GDIPlus_ImageGetHeight($hImage)
    $w = _GDIPlus_ImageGetWidth($hImage)
    $sCLSID = _GDIPlus_EncodersGetCLSID ("JPG")

    $hGraphic3 = _GDIPlus_GraphicsCreateFromHWND ($hGUI3)
    $bitmap3 = _GDIPlus_BitmapCreateFromGraphics($w, $h, $hGraphic3)
    $image3 = _GDIPlus_ImageGetGraphicsContext($bitmap3)
    _GDIPlus_GraphicsDrawImageRectRect ($image3, $hImage, 0, 0, $w, $h, 0, 0, $w, $h)
    _GDIPlus_GraphicsDrawImageRect($hGraphic3, $bitmap3, 0, 0, $w, $h)
    $tParams = _GDIPlus_ParamInit (1)
    $tData = DllStructCreate("int Quality")
    DllStructSetData($tData, "Quality", 100) ;quality 0-100
    $pData = DllStructGetPtr($tData)
    _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData)
    $pParams = DllStructGetPtr($tParams)
    _GDIPlus_ImageSaveToFileEx($bitmap3, $output, $sCLSID, $pParams)

    _GDIPlus_GraphicsDispose ($hGraphic3)
    _GDIPlus_ImageDispose ($hImage)
    _GDIPlus_Shutdown ()

Edited by Rad
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

  • Recently Browsing   0 members

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