Convert BMP 2 JPEG without UseJPEGImageEncoder

Just starting out? Need help? Post your questions and find answers here.
Wolf
Enthusiast
Enthusiast
Posts: 232
Joined: Sat Apr 03, 2004 12:00 pm
Location: S.T

Convert BMP 2 JPEG without UseJPEGImageEncoder

Post by Wolf »

Today when i use JPEGImageEncoder in my first graphic project see size of my exe increase about 40 KB :shock:

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.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post 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.)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post 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
I may look like a mule, but I'm not a complete ass.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

Nice one srod. 8)
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

Sparkie wrote:Nice one srod. 8)
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! :wink:
I may look like a mule, but I'm not a complete ass.
Wolf
Enthusiast
Enthusiast
Posts: 232
Joined: Sat Apr 03, 2004 12:00 pm
Location: S.T

Post by Wolf »

Sparkie wrote:I myself haven't used it, but take a look at http://www.purebasic.fr/english/viewtop ... di+wrapper
Hi dear Sparkie, glad to see you :D

Thanks for the link :wink:

To: srod

Damn... size after compile = 3.50 KB :shock:

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! :shock:
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post 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.
I may look like a mule, but I'm not a complete ass.
Wolf
Enthusiast
Enthusiast
Posts: 232
Joined: Sat Apr 03, 2004 12:00 pm
Location: S.T

Post by Wolf »

Thanks srod, your knowledge do nice help for me :D

But it be really great if we can change jpeg compression in this method :!:
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post 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
---------------------------
superadnim
Enthusiast
Enthusiast
Posts: 480
Joined: Thu Jul 27, 2006 4:06 am

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

:lol: should I bash the keyboard and give up?
:?
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

I don't know. It's not my code, so I don't know where the problem lies.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post by srod »

REMOVED
Last edited by srod on Sun Aug 03, 2008 2:25 pm, edited 1 time in total.
I may look like a mule, but I'm not a complete ass.
srod
PureBasic Expert
PureBasic Expert
Posts: 10589
Joined: Wed Oct 29, 2003 4:35 pm
Location: Beyond the pale...

Post 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?
Last edited by srod on Sun Aug 03, 2008 2:35 pm, edited 1 time in total.
I may look like a mule, but I'm not a complete ass.
Sparkie
PureBatMan Forever
PureBatMan Forever
Posts: 2307
Joined: Tue Feb 10, 2004 3:07 am
Location: Ohio, USA

Post by Sparkie »

@PB: do a Windows search for gdiplus.lib. If found, place a copy in PureBasic\PureLibraries\Windows\Libraries\
What goes around comes around.

PB 5.21 LTS (x86) - Windows 8.1
Wolf
Enthusiast
Enthusiast
Posts: 232
Joined: Sat Apr 03, 2004 12:00 pm
Location: S.T

Post by Wolf »

To: srod
Work very well, thank you so much my friend :D

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