Sign in to follow this  
Followers 0
b0x4it

Resize & Rotate Image

11 posts in this topic

I am using the following code which loads an image and rotate it for 90 degrees and then save it to hard. When the line related to the _GDIPlus_ImageResize is comment out, everything is working perfectly, but when I remove the comment of this line, neither rotation nor resizing works and it does not save anything! What am I doing wrong?

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

Opt("MustDeclareVars", 1)

Global $hBitmap, $hImage1, $hImage, $sCLSID, $tData, $tParams

_GDIPlus_StartUp()

$hImage = _GDIPlus_ImageLoadFromFile("c:\CAM00879.jpg")
;~ $hImage = _GDIPlus_ImageResize($hImage, 100, 80) ;resize image

$sCLSID = _GDIPlus_EncodersGetCLSID("JPG")

$tData  = DllStructCreate("int Rotate")
DllStructSetData($tData, "Rotate", $GDIP_EVTTRANSFORMROTATE90)
$tParams = _GDIPlus_ParamInit(1)
_GDIPlus_ParamAdd($tParams, $GDIP_EPGTRANSFORMATION, 1, $GDIP_EPTLONG , DllStructGetPtr($tData, "Rotate"))

_GDIPlus_ImageSaveToFileEx($hImage, "c:\AutoItImage2.jpg", $sCLSID, DllStructGetPtr($tParams))

_GDIPlus_ShutDown()

Run("MSPaint.exe " & '"c:\AutoItImage2.jpg"')

Share this post


Link to post
Share on other sites



Try this:

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

Opt("MustDeclareVars", 1)

Global $hBitmap, $hImage, $hImage_new, $sCLSID, $tData, $tParams

_GDIPlus_StartUp()

$hImage = _GDIPlus_ImageLoadFromFile("c:\CAM00879.jpg")
$hImage_new = _GDIPlus_ImageResize($hImage, 100, 80) ;resize image
_GDIPlus_ImageRotateFlip($hImage_new, 1)
_GDIPlus_ImageSaveToFile($hImage_new, "c:\AutoItImage2.jpg")
_GDIPlus_ImageDispose($hImage)
_GDIPlus_ImageDispose($hImage_new)
_GDIPlus_ShutDown()

Run("MSPaint.exe " & '"c:\AutoItImage2.jpg"')

Br,

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!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

Try this:

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

Opt("MustDeclareVars", 1)

Global $hBitmap, $hImage, $hImage_new, $sCLSID, $tData, $tParams

_GDIPlus_StartUp()

$hImage = _GDIPlus_ImageLoadFromFile("c:\CAM00879.jpg")
$hImage_new = _GDIPlus_ImageResize($hImage, 100, 80) ;resize image
_GDIPlus_ImageRotateFlip($hImage_new, 1)
_GDIPlus_ImageSaveToFile($hImage_new, "c:\AutoItImage2.jpg")
_GDIPlus_ImageDispose($hImage)
_GDIPlus_ImageDispose($hImage_new)
_GDIPlus_ShutDown()

Run("MSPaint.exe " & '"c:\AutoItImage2.jpg"')

Br,

UEZ

 

This is great, but I am not sure if I can use your code with combination of:

$tParams = _GDIPlus_ParamInit(1)
$tData = DllStructCreate("int Quality") ;create struct to set JPG quality setting
DllStructSetData($tData, "Quality", 50) ;quality 0-100 (0: lowest, 100: highest)
_GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "Quality"))

in order to decrease the quality! Do you know why my code does not work when _GDIPlus_ImageResize is not commented out?

Share this post


Link to post
Share on other sites

Try this (untested):

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

Opt("MustDeclareVars", 1)

Global $hBitmap, $hImage, $hImage_new, $sCLSID, $tData, $tParams, $pData, $pParams, $iJPEG_Quality = 10

_GDIPlus_StartUp()

$hImage = _GDIPlus_ImageLoadFromFile("c:\CAM00879.jpg")
$hImage_new = _GDIPlus_ImageResize($hImage, 100, 80) ;resize image
_GDIPlus_ImageRotateFlip($hImage_new, 1)

$sCLSID = _GDIPlus_EncodersGetCLSID("JPG")
$tParams = _GDIPlus_ParamInit(1)
$tData = DllStructCreate("int Quality")
DllStructSetData($tData, "Quality", $iJPEG_Quality)
$pData = DllStructGetPtr($tData)
_GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData)
$pParams = DllStructGetPtr($tParams)
_GDIPlus_ImageSaveToFileEx($hImage_new, "c:\AutoItImage2.jpg", $sCLSID, $pParams)

_GDIPlus_ImageDispose($hImage)
_GDIPlus_ImageDispose($hImage_new)
_GDIPlus_ShutDown()

Run("MSPaint.exe " & '"c:\AutoItImage2.jpg"')

Currently I don't know why _GDIPlus_ImageSaveToFileEx() fails to save the image created by _GDIPlus_ImageResize().

 

Br,

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!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Try this (untested):

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

Opt("MustDeclareVars", 1)

Global $hBitmap, $hImage, $hImage_new, $sCLSID, $tData, $tParams, $pData, $pParams, $iJPEG_Quality = 10

_GDIPlus_StartUp()

$hImage = _GDIPlus_ImageLoadFromFile("c:\CAM00879.jpg")
$hImage_new = _GDIPlus_ImageResize($hImage, 100, 80) ;resize image
_GDIPlus_ImageRotateFlip($hImage_new, 1)

$sCLSID = _GDIPlus_EncodersGetCLSID("JPG")
$tParams = _GDIPlus_ParamInit(1)
$tData = DllStructCreate("int Quality")
DllStructSetData($tData, "Quality", $iJPEG_Quality)
$pData = DllStructGetPtr($tData)
_GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData)
$pParams = DllStructGetPtr($tParams)
_GDIPlus_ImageSaveToFileEx($hImage_new, "c:\AutoItImage2.jpg", $sCLSID, $pParams)

_GDIPlus_ImageDispose($hImage)
_GDIPlus_ImageDispose($hImage_new)
_GDIPlus_ShutDown()

Run("MSPaint.exe " & '"c:\AutoItImage2.jpg"')

Currently I don't know why _GDIPlus_ImageSaveToFileEx() fails to save the image created by _GDIPlus_ImageResize().

 

Br,

UEZ

 

Your code works perfectly! Thank you very much!

For the issue of _GDIPlus_ImageSaveToFileEx() failing to save the image created by _GDIPlus_ImageResize(), should I report a bug?

Edited by b0x4it

Share this post


Link to post
Share on other sites

Not needed yet. I need to investigate more in detail why this fails.

Br,

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!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

Not needed yet. I need to investigate more in detail why this fails.

Br,

UEZ

 

Ok, please let me know if you found the reason.

Share this post


Link to post
Share on other sites

The reason probably is that the loaded image must be in JPG format. Resizing the image will convert the image to a memory bitmap  format which is not accecpted by the rotation function.

What I did is to compress the memory bitmap to the JPG format and load it afterwards. Then it will work as expected.

 

Br,

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!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

The reason probably is that the loaded image must be in JPG format. Resizing the image will convert the image to a memory bitmap  format which is not accecpted by the rotation function.

What I did is to compress the memory bitmap to the JPG format and load it afterwards. Then it will work as expected.

 

Br,

UEZ

I have no idea how to do it, can you please give me a sample?

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Sure:

#include <Memory.au3>
#include <ScreenCapture.au3>

Example()

Func Example()
    Local $hImage, $hImage2, $sCLSID, $tData, $tParams

    If FileExists(@ScriptDir & "\GDIPlus_Image2.jpg") Then FileDelete(@ScriptDir & "\GDIPlus_Image2.jpg")
    If FileExists(@ScriptDir & "\GDIPlus_Image.jpg") Then FileDelete(@ScriptDir & "\GDIPlus_Image.jpg")
    ; Capture screen
    _ScreenCapture_Capture(@ScriptDir & "\GDIPlus_Image.jpg")

    ; Initialize GDI+ library
    _GDIPlus_Startup()

    ; Load image
    $hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\GDIPlus_Image.jpg")

    $hImage2 = _GDIPlus_ImageResize($hImage, @DesktopWidth / 8, @DesktopHeight / 8, 7)

    $hBitmap_Compressed = _GDIPlus_StreamImage2BinaryString($hImage2, "JPG", 100) ;converting back the memory bitmap to a JPG format
    _GDIPlus_BitmapDispose($hImage2)
    $hImage2 = _GDIPlus_BitmapCreateFromMemory($hBitmap_Compressed) ;load the JPG formatted image

    ; Get JPEG encoder CLSID
    $sCLSID = _GDIPlus_EncodersGetCLSID("JPG")

    ; Set up parameters for 90 degree rotation
    $tData = DllStructCreate("int Data;")
    DllStructSetData($tData, "Data", $GDIP_EVTTRANSFORMROTATE90)

    $tParams = _GDIPlus_ParamInit(1)
    _GDIPlus_ParamAdd($tParams, $GDIP_EPGTRANSFORMATION, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "Data"))

    ; Save image with rotation
    _GDIPlus_ImageSaveToFileEx($hImage2, @ScriptDir & "\GDIPlus_Image2.jpg", $sCLSID, DllStructGetPtr($tParams))


    ; Shut down GDI+ library
    _GDIPlus_Shutdown()

    ShellExecute(@ScriptDir & "\GDIPlus_Image2.jpg")
EndFunc   ;==>Example


Func _GDIPlus_StreamImage2BinaryString($hBitmap, $sFormat = "JPG", $iQuality = 80, $bSave = False, $sFilename = @ScriptDir & "\Converted.jpg") ;coded by UEZ 2013 build 2014-01-25
    Local $sImgCLSID, $tGUID, $tParams, $tData
    Switch $sFormat
        Case "JPG"
            $sImgCLSID = _GDIPlus_EncodersGetCLSID($sFormat)
            $tGUID = _WinAPI_GUIDFromString($sImgCLSID)
            $tData = DllStructCreate("int Quality")
            DllStructSetData($tData, "Quality", $iQuality) ;quality 0-100
            Local $pData = DllStructGetPtr($tData)
            $tParams = _GDIPlus_ParamInit(1)
            _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData)
        Case "PNG", "BMP", "GIF", "TIF"
            $sImgCLSID = _GDIPlus_EncodersGetCLSID($sFormat)
            $tGUID = _WinAPI_GUIDFromString($sImgCLSID)
        Case Else
            Return SetError(1, 0, 0)
    EndSwitch
    Local $hStream = _WinAPI_CreateStreamOnHGlobal() ;http://msdn.microsoft.com/en-us/library/ms864401.aspx
    If @error Then Return SetError(2, 0, 0)
    _GDIPlus_ImageSaveToStream($hBitmap, $hStream, DllStructGetPtr($tGUID), DllStructGetPtr($tParams))
    If @error Then Return SetError(3, 0, 0)

    Local $hMemory = _WinAPI_GetHGlobalFromStream($hStream) ;http://msdn.microsoft.com/en-us/library/aa911736.aspx
    If @error Then Return SetError(4, 0, 0)
    Local $iMemSize = _MemGlobalSize($hMemory)
    If Not $iMemSize Then Return SetError(5, 0, 0)
    Local $pMem = _MemGlobalLock($hMemory)
    $tData = DllStructCreate("byte[" & $iMemSize & "]", $pMem)
    Local $bData = DllStructGetData($tData, 1)
    _WinAPI_ReleaseStream($hStream) ;http://msdn.microsoft.com/en-us/library/windows/desktop/ms221473(v=vs.85).aspx
    _MemGlobalFree($hMemory)
    If $bSave Then
        Local $hFile = FileOpen($sFilename, 18)
        If @error Then Return SetError(6, 0, $bData)
        FileWrite($hFile, $bData)
        FileClose($hFile)
    EndIf
    Return $bData
EndFunc   ;==>_GDIPlus_StreamImage2BinaryString

Br,

UEZ

Edited by UEZ
1 person likes this

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!
¯\_(ツ)_/¯

Share this post


Link to post
Share on other sites

Sure:

#include <Memory.au3>
#include <ScreenCapture.au3>

Example()

Func Example()
    Local $hImage, $hImage2, $sCLSID, $tData, $tParams

    If FileExists(@ScriptDir & "\GDIPlus_Image2.jpg") Then FileDelete(@ScriptDir & "\GDIPlus_Image2.jpg")
    If FileExists(@ScriptDir & "\GDIPlus_Image.jpg") Then FileDelete(@ScriptDir & "\GDIPlus_Image.jpg")
    ; Capture screen
    _ScreenCapture_Capture(@ScriptDir & "\GDIPlus_Image.jpg")

    ; Initialize GDI+ library
    _GDIPlus_Startup()

    ; Load image
    $hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\GDIPlus_Image.jpg")

    $hImage2 = _GDIPlus_ImageResize($hImage, @DesktopWidth / 8, @DesktopHeight / 8, 7)

    $hBitmap_Compressed = _GDIPlus_StreamImage2BinaryString($hImage2, "JPG", 100) ;converting back the memory bitmap to a JPG format
    _GDIPlus_BitmapDispose($hImage2)
    $hImage2 = _GDIPlus_BitmapCreateFromMemory($hBitmap_Compressed) ;load the JPG formatted image

    ; Get JPEG encoder CLSID
    $sCLSID = _GDIPlus_EncodersGetCLSID("JPG")

    ; Set up parameters for 90 degree rotation
    $tData = DllStructCreate("int Data;")
    DllStructSetData($tData, "Data", $GDIP_EVTTRANSFORMROTATE90)

    $tParams = _GDIPlus_ParamInit(1)
    _GDIPlus_ParamAdd($tParams, $GDIP_EPGTRANSFORMATION, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "Data"))

    ; Save image with rotation
    _GDIPlus_ImageSaveToFileEx($hImage2, @ScriptDir & "\GDIPlus_Image2.jpg", $sCLSID, DllStructGetPtr($tParams))


    ; Shut down GDI+ library
    _GDIPlus_Shutdown()

    ShellExecute(@ScriptDir & "\GDIPlus_Image2.jpg")
EndFunc   ;==>Example


Func _GDIPlus_StreamImage2BinaryString($hBitmap, $sFormat = "JPG", $iQuality = 80, $bSave = False, $sFilename = @ScriptDir & "\Converted.jpg") ;coded by UEZ 2013 build 2014-01-25
    Local $sImgCLSID, $tGUID, $tParams, $tData
    Switch $sFormat
        Case "JPG"
            $sImgCLSID = _GDIPlus_EncodersGetCLSID($sFormat)
            $tGUID = _WinAPI_GUIDFromString($sImgCLSID)
            $tData = DllStructCreate("int Quality")
            DllStructSetData($tData, "Quality", $iQuality) ;quality 0-100
            Local $pData = DllStructGetPtr($tData)
            $tParams = _GDIPlus_ParamInit(1)
            _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData)
        Case "PNG", "BMP", "GIF", "TIF"
            $sImgCLSID = _GDIPlus_EncodersGetCLSID($sFormat)
            $tGUID = _WinAPI_GUIDFromString($sImgCLSID)
        Case Else
            Return SetError(1, 0, 0)
    EndSwitch
    Local $hStream = _WinAPI_CreateStreamOnHGlobal() ;http://msdn.microsoft.com/en-us/library/ms864401.aspx
    If @error Then Return SetError(2, 0, 0)
    _GDIPlus_ImageSaveToStream($hBitmap, $hStream, DllStructGetPtr($tGUID), DllStructGetPtr($tParams))
    If @error Then Return SetError(3, 0, 0)

    Local $hMemory = _WinAPI_GetHGlobalFromStream($hStream) ;http://msdn.microsoft.com/en-us/library/aa911736.aspx
    If @error Then Return SetError(4, 0, 0)
    Local $iMemSize = _MemGlobalSize($hMemory)
    If Not $iMemSize Then Return SetError(5, 0, 0)
    Local $pMem = _MemGlobalLock($hMemory)
    $tData = DllStructCreate("byte[" & $iMemSize & "]", $pMem)
    Local $bData = DllStructGetData($tData, 1)
    _WinAPI_ReleaseStream($hStream) ;http://msdn.microsoft.com/en-us/library/windows/desktop/ms221473(v=vs.85).aspx
    _MemGlobalFree($hMemory)
    If $bSave Then
        Local $hFile = FileOpen($sFilename, 18)
        If @error Then Return SetError(6, 0, $bData)
        FileWrite($hFile, $bData)
        FileClose($hFile)
    EndIf
    Return $bData
EndFunc   ;==>_GDIPlus_StreamImage2BinaryString

Br,

UEZ

Great, thank you very much!

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  
Followers 0