Download the SaveJPEG Project (including ijl11.dll) (150kb)
Updated! 21 March 2000
Intel have now released version 1.1 of this
library (ijl11.dll) so the sample has been updated to use this version. There are no
functional changes in this version but it is supposedly quicker and includes some minor bug fixes.
Added LoadJPGFromPtr and SaveJPGToPtr. These methods allow you to load
and save the JPEG to a byte array or memory block rather than Save to disk.
Updated! 15 August 1999
The last version of this code corrupted images when asked to load or save files which
weren't an even multiple of 4 bytes across (the result was a diagonal distortion).
This was because DIB files are padded to 4 byte (i.e. 32 bit) boundaries, but my interface to
the JPG library assumed no alignment. I missed this because (get this !) I tested with only
8 images, and all of them were a multiple of 4 in width...
It is better now, and I also added some information about the Performance of
The Quality argument has been added to the SaveJPG method, allowing you to specify the
quality/compression of the saved JPG image.
Whilst Visual Basic provides support for loading graphic files in various formats into a StdPicture object,
it sadly forgets about all of these when it comes to saving the file again. You normally only have
one choice of file format for writing: a BMP at the system colour depth.
Whilst there are various third party controls available to save files in other formats, these are
often have unacceptable 'per seat' licensing policies and can be incredibly expensive. This article
shows how to use a free JPEG DLL library to save VB pictures.
JPEG File Format
The JPEG file format is aimed at providing very high compression levels for photographic quality images.
Before deciding whether you want to use JPEG files in any application you write, there are points to
consider about how JPEG operates.
- High compression ratio
- Wide support - thanks to the free availability of source code to implement JPG read and write, many
applications support it. Windows 98 and 2000 even include native support for reading JPG files.
- No license requirements, unlike GIF.
The Independent JPEG Group have done a great deal to make the JPEG
format much more accessible to developers by providing free, platform independent C source code to
implement JPEG load and save functions. Their library is used in Internet Explorer *,
Netscape * Navigator and countless other projects (some of which have even have the audacity to
charge for free code!), including a JPEG Library DLL, ijl11.dll,
available from the Intel* Developer Site.
- The JPEG format is lossy: colour accuracy is affected when you save the file. Images saved to JPEG
many times loose quality in a similar way that multiple generations of analogue recordings do.
- It is difficult to encode - not a task you would like to perform in VB code!
- Works on true colour (24 bit images); not suitable as a format for storing files aimed at paletised systems.
This DLL makes conversion to and from JPG simpler by working on a DIB byte format. This makes it
easier to use for Windows programmers than the Independent JPEG Group's C code, since the input and
output format in memory is a standard Windows format. Conversion between VB StdPicture objects and
a DIB is achieved using the cDIBSection Class.
Download the sample project. This contains all the files required.
Firstly, unzip Ijl11.zip and place ijl11.dll in your system's path (ideally in the Windows\System directory).
Read the licensing agreement included in the zip. If you are going to use this file for a distributed or
commercial project you must download a registered copy (free) from Intel at their
JPEG Library page.
Then there are two VB files needed:
mIJL.bas contains the declares for ijl11.dll and four wrapper functions:
All these function accept an instance of the cDIBSection Class. The standard versions
of the functions accept a file name as an argument, while the Ptr versions accept a
long value pointing to a memory buffer and a variable indicating the buffer size.
Although VB can already load a JPG, LoadJPG is provided as it gives a shortcut for loading
a JPG file directly into a cDIBSection class without requiring a StdPicture object.
LoadJPGFromPtr allows you to load a JPG directly from a byte array containing the JPG, a
function which can't be otherwise be achieved easily in VB.
To save a StdPicture object directly, you need to do this:
Dim c As New cDibSection
' Convert Picture object to DIBSection:
' Save it:
SaveJPG c, sFileName
Saving and Loading From Memory Buffers
To Load a JPG from a memory buffer, first you create a byte array containing all the
bytes in the JPG, or use the Shell's IMalloc implementation
to allocate memory directly and have that contain the JPG bytes. Then you pass the pointer
to the data and the size of the buffer into the LoadJPGFromPtr method. If you
use a byte array, the pointer is obtained using VB's VarPtr function:
' Assuming the byte array is b():
lPtr = VarPtr(b(0))
To save a JPG to a memory buffer directly, you need to create a byte array or allocate
sufficient memory to hold the resultant JPG. Normally this means creating a larger buffer
than the resulting JPG. Since JPG always compresses an image, the size is always going
to be smaller than the size of an equivalent DIB buffer to hold the bytes. In the sample
code I chose 1/4 of the bytes in the DIBSection (m_cDib.Height * m_cDib.BytesPerScanLine / 4).
Then you pass a pointer to this buffer and its size to the SaveJPGFromPtr. The
method modifies the size variable passed in to reflect the actual size of the JPG created
which you can then use to trim down the buffer to size.
Interestingly, using cDIBSection with the Intel JPG library can be substantially faster than than using
VB's standard methods. The following code was used for benchmarking. In the VB case, a new StdPicture
object is created and loaded with a JPG file. For the IJL library, a new cDIBSection object is
created and the same JPG file is loaded:
Private Sub cmdIJL_Click()
Dim fT As Double
Dim cD As New cDIBSection
fT = Timer
LoadJPG cD, App.Path & "\earth.jpg"
Debug.Print "Time:", Timer - fT
Private Sub cmdVB_Click()
Dim fT As Double
Dim picThis As New StdPicture
fT = Timer
Set picThis = LoadPicture(App.Path & "\earth.jpg")
Debug.Print "Time:", Timer - fT
The tested file, earth.jpg, was a 1022x747 pixel JPG, with a file size of 66kb. Performance on the test
machine (Pentium II 266 with 256Mb memory) showed the IJL library version to be more than twice
as quick as the VB version. Typically, VB turned in a load speed of around 1 second,
whilst the IJL version achieved around 0.4s.
Back to top
Back to vbMedia Source Code Overview
Back to Source Code Overview