Page 1 of 2
Convert BMP 2 JPEG without UseJPEGImageEncoder
Posted: Sat Aug 02, 2008 12:58 pm
by Wolf
Today when i use JPEGImageEncoder in my first graphic project see size of my exe increase about 40 KB
Why size of this librarie is so big? If exist another Userlibrary,dll, command line program or ..... to convert from bmp to jpeg with less size please presentation it.
Posted: Sat Aug 02, 2008 1:07 pm
by Sparkie
I myself haven't used it, but take a look at
http://www.purebasic.fr/english/viewtop ... di+wrapper
(40kb = a drop in the bucket IMO.)
Posted: Sat Aug 02, 2008 1:56 pm
by srod
Code: Select all
#GDIPLUS_OK = 0
;-Structures.
Structure GdiplusStartupInput ;{
GdiPlusVersion.l
*DebugEventCallback.DebugEventProc
SuppressBackgroundThread.l
SuppressExternalCodecs.l
EndStructure
;-Imports.
Import "gdiplus.lib"
GdiplusStartup(token, *input.GdiplusStartupInput, output)
GdiplusShutdown(token)
GdipCreateBitmapFromFile(filename.p-unicode, *bitmap)
GdipSaveImageToFile(image, filename.p-unicode, *clsidEncoder.CLSID, *encoderParams)
GdipDisposeImage(image)
EndImport
;First initialise gdi+.
input.GdiplusStartupInput
input\GdiPlusVersion = 1
GdiplusStartup(@token, @input, #Null)
;Was the initialisation successful?
If token
If GdipCreateBitmapFromFile("test.bmp", @image) = #GDIPLUS_OK
GdipSaveImageToFile(image, "test.jpg", ?clsid_jpeg, 0)
GdipDisposeImage(image)
EndIf
;Tidy up.
GdiplusShutdown(token)
EndIf
End
;CLSID for the gdi+ jpeg encoder.
DataSection
clsid_jpeg:
Data.l $557CF401
Data.w $1A04, $11D3
Data.b $9A, $73, $00, $00, $F8, $1E, $F3, $2E
EndDataSection
Posted: Sat Aug 02, 2008 2:52 pm
by Sparkie
Nice one srod.

Posted: Sat Aug 02, 2008 2:56 pm
by srod
Sparkie wrote:Nice one srod.

t'was nothing really, -all I did was enumerate the encoder clsid's and use some old code I had for saving png's using gdi+.
@Wolf : note that gdi+ is only available on XP onwards. For a crossplatform solution there is the freeImage library -although bitmaps have to be converted to 24-bit first before attempting to save as a jpeg. This library is very good, but is somewhat larger than 40 kb!

Posted: Sat Aug 02, 2008 11:23 pm
by Wolf
Hi dear Sparkie, glad to see you
Thanks for the link
To: srod
Damn... size after compile = 3.50 KB
I'm confounded .....

How does this working? i don't hear any about gdi+ until today, it's like API include in windows? or maybe i must put gdiplus.lib library always in project folder?
Anyway how can i change jpeg compression rate in this source?
And at end big thanks for this magical code.... shock again!

Posted: Sun Aug 03, 2008 10:57 am
by srod
Hi Wolf,
the gdi+ library comes pre-installed on XP, 2003 and Vista. For other systems you need to copy the gdi+redistributable etc.
As for jpeg compression; sorry, my knowledge of jpeg and gdi+ is 'functional' at best!

I will take a real good look at gdi+ at some point.
Posted: Sun Aug 03, 2008 12:46 pm
by Wolf
Thanks srod, your knowledge do nice help for me
But it be really great if we can change jpeg compression in this method

Posted: Sun Aug 03, 2008 1:26 pm
by PB
> gdi+ is only available on XP onwards
Not on all XP. When I run the code on XP Pro (SP3) I get this error:
Code: Select all
---------------------------
PureBasic - Linker error
---------------------------
POLINK: fatal error: File not found: 'gdiplus.lib'.
---------------------------
OK
---------------------------
Posted: Sun Aug 03, 2008 2:07 pm
by superadnim
But that means your PB installation doesn't have the library file so the linker can't do anything about your code... It doesn't mean the system doesn't have the DLL though, right?.
Posted: Sun Aug 03, 2008 2:09 pm
by PB
I don't know. It's not my code, so I don't know where the problem lies.
Posted: Sun Aug 03, 2008 2:10 pm
by srod
REMOVED
Posted: Sun Aug 03, 2008 2:21 pm
by srod
Here is the gdi+ code for saving a bitmap in jpeg format with a specified compression level (0 = max compression, 100 = least compression) :
Code: Select all
#GDIPLUS_OK = 0
Enumeration
#EncoderParameterValueTypeByte = 1
#EncoderParameterValueTypeASCII = 2
#EncoderParameterValueTypeShort = 3
#EncoderParameterValueTypeLong = 4
#EncoderParameterValueTypeRational = 5
#EncoderParameterValueTypeLongRange = 6
#EncoderParameterValueTypeUndefined = 7
#EncoderParameterValueTypeRationalRange = 8
#EncoderParameterValueTypePointer = 9
EndEnumeration
;-Structures.
Structure GdiplusStartupInput
GdiPlusVersion.l
*DebugEventCallback.DebugEventProc
SuppressBackgroundThread.l
SuppressExternalCodecs.l
EndStructure
;The following two structures are used for setting encoder parameters (in our case the 'quality' parameter).
Structure EncoderParameter
guid.GUID
NumberOfValues.l
Type.l
Value.l
EndStructure
Structure EncoderParameters
Count.i
Parameter.EncoderParameter[1]
EndStructure
;-Imports.
Import "gdiplus.lib"
GdiplusStartup(token, *input.GdiplusStartupInput, output)
GdiplusShutdown(token)
GdipCreateBitmapFromFile(filename.p-unicode, *bitmap)
GdipSaveImageToFile(image, filename.p-unicode, *clsidEncoder.CLSID, *encoderParams)
GdipDisposeImage(image)
EndImport
;Returns #True if succesful.
Procedure.l GdipSaveImageToJpeg(sourceFile$, destinationFile$, compression.l=100) ;Compression = 0 for max compression, 100 for least.
Protected result, token, image
Protected input.GdiplusStartupInput, encParams.EncoderParameters
;First initialise gdi+.
input\GdiPlusVersion = 1
GdiplusStartup(@token, @input, #Null)
;Was the initialisation successful?
If token
If GdipCreateBitmapFromFile(sourceFile$, @image) = #GDIPLUS_OK
;Sort out the compression.
With encParams
\Count = 1
CopyMemory(?clsid_EncoderQuality, @\Parameter[0]\guid, SizeOf(GUID))
\Parameter[0]\Type = #EncoderParameterValueTypeLong
\Parameter[0]\NumberOfValues = 1
\Parameter[0]\Value = @compression
EndWith
If GdipSaveImageToFile(image, destinationFile$, ?clsid_jpeg, encParams) = #GDIPLUS_OK
result = #True
EndIf
GdipDisposeImage(image)
EndIf
;Tidy up.
GdiplusShutdown(token)
EndIf
ProcedureReturn result
EndProcedure
DataSection
;CLSID for the gdi+ jpeg encoder.
clsid_jpeg:
Data.l $557CF401
Data.w $1A04, $11D3
Data.b $9A, $73, $00, $00, $F8, $1E, $F3, $2E
;CLSID for the relevant gdi+ encoder parameter.
clsid_EncoderQuality:
Data.l $1D5BE4B5
Data.w $FA4A, $452D
Data.b $9C, $DD, $5D, $B3, $51, $05, $E7, $EB
EndDataSection
;Test.
Debug GdipSaveImageToJpeg("test.bmp", "test.jpg", 0) ;Compression = 0 for max compression, 100 for least.
@PB : your system will have the gdiplus.dll for sure. The import library is a different matter though - either you have it or you do not!

I can upload one somewhere if you need?
Posted: Sun Aug 03, 2008 2:28 pm
by Sparkie
@PB: do a Windows search for gdiplus.lib. If found, place a copy in PureBasic\PureLibraries\Windows\Libraries\
Posted: Sun Aug 03, 2008 10:52 pm
by Wolf
To: srod
Work very well, thank you so much my friend
To: PB
Just go to Sparkie link at post number 2 and download:
http://home.comcast.net/~sfsxoi/gdiplus11_v3a.zip
After extract you see GdiPlus.lib in files just copy this file to folder of saved srod source, after compile and create exe you dont need more GdiPlus.lib in that folder.