Jump to content

Recommended Posts

The real challenge here is to determine the right size of the memory needed to be allocated for the stream. I have no idea how to do that.

But regardless of that, I can do this:

Opt("MustDeclareVars", 1)

#include <GDIPlus.au3>
#include <Memory.au3>


Local $sImage = FileOpenDialog("Image file", "", "Images (*.bmp;*.gif;*.jpg;*.png)")
If @error Then Exit

_GDIPlus_Startup()

Global $hImage = _GDIPlus_ImageLoadFromFile($sImage)

Global $bNewImage = _GDIPlus_ImageSaveToVariable($hImage, "jpg")

_GDIPlus_ImageDispose($hImage)

Global $hNewPicFile = FileOpen(@DesktopDir & "\NewPic.jpg", 26)
FileWrite($hNewPicFile, $bNewImage)
FileClose($hNewPicFile)

_GDIPlus_Shutdown()




Func _GDIPlus_ImageSaveToVariable($hImage, $sNewFormat)

    Local $iSize = 100000 ; !determinig optimal (right) value is the real challenge!

    Local $sCLSID = _GDIPlus_EncodersGetCLSID($sNewFormat)

    Local $tGUID = _WinAPI_GUIDFromString($sCLSID)
    Local $pGUID = DllStructGetPtr($tGUID)

    Local $hMemory = _MemGlobalAlloc($iSize, 2)
    Local $pMemory = _MemGlobalLock($hMemory)

    Local $a_iCall = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", _
            "ptr", $pMemory, _
            "int", 1, _
            "ptr*", 0)

    Local $pStream = $a_iCall[3]

    $a_iCall = DllCall($ghGDIPDll, "int", "GdipSaveImageToStream", _
            "ptr", $hImage, _
            "ptr", $pStream, _
            "ptr", $pGUID, _
            "ptr", 0)

    Local $tVariable = DllStructCreate("byte[" & $iSize & "]", $pMemory)
    _MemGlobalUnlock($hMemory)

    Return DllStructGetData($tVariable, 1)

EndFunc

It will get you image in desired format in form of variable. You can do whatever you want with it afterward. In that example I saved to a file.

Btw, error checking is missing.

Edited by trancexx

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Awesome, thanks a lot, trancexx, it's exactly what I was looking for. It is crashing AutoIt3.exe on certain files, but I think I should easily be able to add the error checking and figure out what's going wrong. It's possible that there is just be something wrong with the actual files.

As for the size variable, the original script I found used the Binary Length of the image. Of course, since I'm converting to Jpeg, most files should see a size decrease. I've noticed that if the size is too small then the image gets cut off, and if it's too big then the file is padded with Null characters.

Right now the only thing I can think of is to keep track of the characters as they are being written to the file, and stop writing if a certain number of consecutive Null characters are encountered. I'll have to experiment with it a bit and see what I can come up with.

EDIT: I've determined that the crash is occurring at the Return line, but have no idea why. If I open the (jpg) image with Paint.net and save it as a png, the script works fine and converts it to a jpg.

It's crashing because of the wrong size.

I did some thinking (...well, every now and then I do) and this looks like the real thing:

Opt("MustDeclareVars", 1)

#include <GDIPlus.au3>
#include <Memory.au3>


Local $sImage = FileOpenDialog("Image file", "", "Images (*.bmp;*.gif;*.jpg;*.png)")
If @error Then Exit

_GDIPlus_Startup()

Global $hImage = _GDIPlus_ImageLoadFromFile($sImage)

Global $sType = "bmp"

Global $bNewImage = _GDIPlus_ImageSaveToVariable($hImage, $sType)

_GDIPlus_ImageDispose($hImage)

_GDIPlus_Shutdown()

Global $hNewPicFile = FileOpen(@DesktopDir & "\NewPic." & $sType, 26)
FileWrite($hNewPicFile, $bNewImage)
FileClose($hNewPicFile)






Func _GDIPlus_ImageSaveToVariable($hImage, $sNewFormat)

    Local $sCLSID = _GDIPlus_EncodersGetCLSID($sNewFormat)

    Local $tGUID = _WinAPI_GUIDFromString($sCLSID)
    Local $pGUID = DllStructGetPtr($tGUID)

    Local $a_iCall = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", _
            "ptr", 0, _ ; internally allocate
            "int", 1, _ ; automatically free
            "ptr*", 0)

    Local $pStream = $a_iCall[3]

    $a_iCall = DllCall($ghGDIPDll, "int", "GdipSaveImageToStream", _
            "ptr", $hImage, _
            "ptr", $pStream, _
            "ptr", $pGUID, _
            "ptr", 0)

    $a_iCall = DllCall("ole32.dll", "int", "GetHGlobalFromStream", _
            "ptr", $pStream, _
            "ptr*", 0)

    Local $hMemory = $a_iCall[2]

    $a_iCall = DllCall("kernel32.dll", "dword", "GlobalSize", "ptr", $hMemory)

    Local $iNewSize = $a_iCall[0]

    $hMemory = _MemGlobalAlloc($iNewSize, 2) ; allocate in correct size
    Local $pMemory = _MemGlobalLock($hMemory) ; get pointer
    _MemGlobalUnlock($hMemory)

    $a_iCall = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", _
            "ptr", $pMemory, _
            "int", 1, _ ; automatically free
            "ptr*", 0)

    $pStream = $a_iCall[3] ; new stream

    $a_iCall = DllCall($ghGDIPDll, "int", "GdipSaveImageToStream", _
            "ptr", $hImage, _
            "ptr", $pStream, _
            "ptr", $pGUID, _
            "ptr", 0)

    Local $tBinary = DllStructCreate("byte[" & $iNewSize & "]", $pMemory)

    Local $bBinary = DllStructGetData($tBinary, 1)

    DllCall("kernel32.dll", "int", "GlobalFree", "ptr", $hMemory)

    Return $bBinary

EndFunc   ;==>_GDIPlus_ImageSaveToVariable

It needs testing.

Edited by trancexx

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

  • 1 month later...

What a Wonderful World

I see trees of green, red roses too

I see them bloom for me and you

And I think to myself, what a wonderful world

I see skies of blue and clouds of white

The bright blessed day, the dark sacred night

And I think to myself, what a wonderful world

The colours of the rainbow, so pretty in the sky

Are also on the faces of people going by

I see friends shakin' hands, sayin' "How do you do?"

They're really saying "I love you"

I hear babies cryin', I watch them grow

They'll learn much more than I'll ever know

And I think to myself, what a wonderful world

Yes, I think to myself, what a wonderful world

Oh yeah

Louis Armstrong performing

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

What a Wonderful World

I see trees of green, red roses too

I see them bloom for me and you

And I think to myself, what a wonderful world

I see skies of blue and clouds of white

The bright blessed day, the dark sacred night

And I think to myself, what a wonderful world

The colours of the rainbow, so pretty in the sky

Are also on the faces of people going by

I see friends shakin' hands, sayin' "How do you do?"

They're really saying "I love you"

I hear babies cryin', I watch them grow

They'll learn much more than I'll ever know

And I think to myself, what a wonderful world

Yes, I think to myself, what a wonderful world

Oh yeah

Louis Armstrong performing

Erm...What?
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...