Jump to content

GDIPlus Change Quality + Scale


Rad
 Share

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)
            _GDIPlus_ImageDispose($hImage)
            $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"))
    EndSwitch
    If IsDllStruct($tParams) Then $pParams = DllStructGetPtr($tParams)

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

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

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("")


_GDIPlus_Startup()
$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)

_Main()

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)
    GUISetState()

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

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

    ; 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)
    _WinAPI_DeleteObject($bitmap1)
    _GDIPlus_GraphicsDispose($image1)

    ; 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)
    _WinAPI_DeleteObject($bitmap2)
    _GDIPlus_GraphicsDispose($image2)
    $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)
    _WinAPI_DeleteObject($bitmap3)
    _GDIPlus_GraphicsDispose($image3)

    ; 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
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE

    Exit

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:

UEZ

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

Edit:

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)
    GUISetState()

    _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)
    GUIDelete($hGUI3)
    _WinAPI_DeleteObject($bitmap3)
    _GDIPlus_GraphicsDispose($image3)

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

    FileDelete($name)
endfunc
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
 Share

  • Recently Browsing   0 members

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