Sign in to follow this  
Followers 0
nullschritt

Converting bmp to jpeg with gdi+

7 posts in this topic

Hello all I am attempting to convert BMP file to JPEG to reduce their size, below is the code I am currently trying to use.

_GDIPlus_Startup()
$hImage = _GDIPlus_BitmapCreateFromFile($snapfile) ;$snapfile is the origin BMP file
$ret = Bitmap2BinaryString($himage, 60)
_GDIPlus_BitmapDispose($hImage)
_WinAPI_DeleteObject($hImage)
_GDIPlus_Shutdown()
FileWrite("ss.jpg", binary($ret))

Func Bitmap2BinaryString($hBitmap, $JPEG_Quality = 90) ;code by Andreik, modified by UEZ
    Local $declared = True
    If Not $ghGDIPDll Then
        _GDIPlus_Startup()
        $declared = False
    EndIf
    Local $STREAM = DllCall("ole32.dll", "uint", "CreateStreamOnHGlobal", "ptr", 0, "bool", 1, "ptr*", 0)
    $STREAM = $STREAM[3]
    Local $JPG_ENCODER = _GDIPlus_EncodersGetCLSID("JPG")
    Local $TAG_ENCODER = _WinAPI_GUIDFromString($JPG_ENCODER)
    Local $PTR_ENCODER = DllStructGetPtr($TAG_ENCODER)
    Local $tParams = _GDIPlus_ParamInit (1)
    Local $tData = DllStructCreate("int Quality")
    DllStructSetData($tData, "Quality", $JPEG_Quality)
    Local $pData = DllStructGetPtr($tData)
    _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData)
    Local $pParams = DllStructGetPtr($tParams)
    DllCall($ghGDIPDll, "uint", "GdipSaveImageToStream", "ptr", $hBitmap, "ptr", $STREAM, "ptr", $PTR_ENCODER, "ptr", $pParams)
    $tData = 0
    $tParams = 0
    Local $MEMORY = DllCall("ole32.dll", "uint", "GetHGlobalFromStream", "ptr", $STREAM, "ptr*", 0)
    $MEMORY = $MEMORY[2]
    Local $MEM_SIZE = _MemGlobalSize($MEMORY)
    Local $MEM_PTR = _MemGlobalLock($MEMORY)
    Local $DATA_STRUCT = DllStructCreate("byte[" & $MEM_SIZE & "]", $MEM_PTR)
    Local $DATA = DllStructGetData($DATA_STRUCT, 1)
    Local $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr")
    Local $aCall = DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $STREAM, "dword", 8 + 8 * @AutoItX64, "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVARIANT))
    _MemGlobalFree($MEMORY)
    If Not $declared Then _GDIPlus_Shutdown()
    Return $DATA
EndFunc

Every time I try this code the resulting jpeg file is only 4bytes in size, can anyone see what what might be causing this, or what I might be doing wrong?

Share this post


Link to post
Share on other sites



#3 ·  Posted (edited)

Why you are using Bitmap2BinaryString() to convert the bmp to jpg?

Here a function to convert and save an image in JPG format:

 

#include <GDIPlus.au3>

$sFile = FileOpenDialog("Select a non jpg image", "", "Bitmap (*.bmp;*png;*.gif;*tif)")
If @error Then Exit

_GDIPlus_Startup()
If SaveBmp2JPG($sFile) Then ShellExecute("Converted.jpg")
_GDIPlus_Shutdown()

Func SaveBmp2JPG($Bitmap, $sSave = "Converted.jpg", $iQuality = 90) ;coded by UEZ 2013
    If Not IsPtr($Bitmap) Then
        $Bitmap = _GDIPlus_ImageLoadFromFile($sFile)
        If @error Then Return SetError(1, 0, 0)
    EndIf
    Local $sCLSID = _GDIPlus_EncodersGetCLSID("JPG")
    Local $tParams = _GDIPlus_ParamInit(1)
    Local $tData = DllStructCreate("int Quality")
    Local $pData = DllStructGetPtr($tData)
    Local $pParams = DllStructGetPtr($tParams)
    DllStructSetData($tData, "Quality", $iQuality)
    _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData)
    If Not _GDIPlus_ImageSaveToFileEx($Bitmap, $sSave, $sCLSID, $pParams) Then Return SetError(2, 0, 0)
    Return True
EndFunc
 

Br,

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!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Share this post


Link to post
Share on other sites

Because I want the resulting binary, the data is not going to be saved to a file, it is going to be streamed over a network, a file write/read will slow the process down as it already has to do a fileread, to read the contents of the BMP, I want to get the binary of the resulting jpeg without saving to a file.

Share this post


Link to post
Share on other sites

what's your OS ?


[color=rgb(255,0,0);][font="'comic sans ms', cursive;"]FukuLeaks[/color][/font]

Share this post


Link to post
Share on other sites

My OS is windows 7, although I don;t understand why you need to know? The same autoit code should work on all version of windows correct?

Share this post


Link to post
Share on other sites

Why you are using Bitmap2BinaryString() to convert the bmp to jpg?

Here a function to convert and save an image in JPG format:

 

#include <GDIPlus.au3>

$sFile = FileOpenDialog("Select a non jpg image", "", "Bitmap (*.bmp;*png;*.gif;*tif)")
If @error Then Exit

_GDIPlus_Startup()
If SaveBmp2JPG($sFile) Then ShellExecute("Converted.jpg")
_GDIPlus_Shutdown()

Func SaveBmp2JPG($Bitmap, $sSave = "Converted.jpg", $iQuality = 90) ;coded by UEZ 2013
    If Not IsPtr($Bitmap) Then
        $Bitmap = _GDIPlus_ImageLoadFromFile($sFile)
        If @error Then Return SetError(1, 0, 0)
    EndIf
    Local $sCLSID = _GDIPlus_EncodersGetCLSID("JPG")
    Local $tParams = _GDIPlus_ParamInit(1)
    Local $tData = DllStructCreate("int Quality")
    Local $pData = DllStructGetPtr($tData)
    Local $pParams = DllStructGetPtr($tParams)
    DllStructSetData($tData, "Quality", $iQuality)
    _GDIPlus_ParamAdd($tParams, $GDIP_EPGQUALITY, 1, $GDIP_EPTLONG, $pData)
    If Not _GDIPlus_ImageSaveToFileEx($Bitmap, $sSave, $sCLSID, $pParams) Then Return SetError(2, 0, 0)
    Return True
EndFunc
 

Br,

UEZ

 

This works perfect but how can I go about returning the binary data as a string rather than saving it to the hard disk?

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