Jump to content

Converting bmp to jpeg with gdi+


Recommended Posts

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?

Link to comment
Share on other sites

#include <GDIPlus.au3>
_GDIPlus_Startup()
$O_Image=_GDIPlus_ImageLoadFromFile($snapfile)
_GDIPlus_ImageSaveToFile($O_Image,"ss.jpg")
DllCall($ghGDIPDll,"int","GdipDisposeImage","handle",$O_Image)
_GDIPlus_Shutdown()

.

isn't that good enough ?

E.

Edited by Edano

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

Link to comment
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

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

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.

Link to comment
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?

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