Click here to Skip to main content
Click here to Skip to main content

Load, show and convert miscellaneous file-formats using freeimage

By , 1 May 2002
 

Sample Image

Introduction

In this article I want to show the following:

  • load, convert and save various file formats (tif, bmp, jpeg, ico, jif, jfif, koa, pcd, pcx, png, pbm, pgm, ppm, ras, targa, tga)
  • supporting multipage-images
  • convert color-model (1bit ... 256 colors ... 16 bit ... 24 bit ... 32 bit)
  • tile the images in horizontal or vertical order
  • integrating freeimage in own projects
  • a sample mdi application with some simple techniques like
    explorer-drag/drop
    a file-open-box for selecting multiple files
    background-threads for long-duration-tasks (e.g. loading images)
  • zooming and scrollbars
  • improved drawing-speed (using the clipping region)
  • drag/drop from explorer

The Graphics-Suite

Opening and Saving

These functions are implemented using freeimage (see below). The code for opening and saving looks is very simple and looks like this (simplified):

BOOL CGraphicSuiteDoc::OnOpenDocument(LPCTSTR lpszPathName) 
{
    FREE_IMAGE_FORMAT    fif;
    
    DeleteContents();

    fif = FreeImage_GetFIFFromFilename(lpszPathName);
    if( fif != FIF_UNKNOWN )
        m_handleFI = FreeImage_Load(fif, lpszPathName);
    
    return (m_handleFI != NULL);
}

void CGraphicSuiteDoc::OnFileSaveAs() 
{
    CString           filter,
                      szDest;
    DWORD             dwFlags = OFN_OVERWRITEPROMPT | 
                                OFN_EXPLORER | 
                                OFN_LONGNAMES | 
                                OFN_PATHMUSTEXIST | 
                                OFN_HIDEREADONLY;
    FREE_IMAGE_FORMAT fif;
    BOOL              bErg;

    filter.LoadString(IDS_STRING_FILTER_GRAPHICS);
    
    CFileDialog    dlg(FALSE, NULL, szDest, dwFlags, filter, 
                       AfxGetMainWnd());

    if(  dlg.DoModal() != IDOK)
        return;
    
    fif = FreeImage_GetFIFFromFilename(dlg.GetPathName());
    if( fif == FIF_UNKNOWN )
    {
        AfxMessageBox("Unknown type.");
        return;
    }

    bErg = FALSE;
    try
    {
        bErg = FreeImage_Save(fif, m_handleFI, dlg.GetPathName());
    }
    catch(...)
    {
    }
    
    if( !bErg )
        AfxMessageBox("Failed saving !");
}

Display and Printing

The MDI-sample uses freeimage to do all the image-stuff, except the display. In this sample the display is handled using the API-function StretchDIBits. In the real-code also the clip-box is used in order only to extract the pixels that have to be repainted. Thus the code shown here is a little simplified to the the technique. I've choosen mapping-mode MM_HIMETRIC, because then you can print the images using the correct resolution and metrics.

void CGraphicSuiteView::OnDraw(CDC* pDC)
{
    CGraphicSuiteDoc    *pDoc = GetDocument();
    
    pDC->SetMapMode(MM_HIMETRIC);

    double dpiX   = FreeImage_GetDotsPerMeterX(pDoc->m_handleFI),
           dpiY   = FreeImage_GetDotsPerMeterY(pDoc->m_handleFI),
           width  = FreeImage_GetWidth(pDoc->m_handleFI),
           height = FreeImage_GetHeight(pDoc->m_handleFI),
           sizeX,    // 1/100 mm == HIMETRIC
           sizeY;
    BYTE    *pData    = FreeImage_GetBits(pDoc->m_handleFI);

    if( dpiX==0.0 )    dpiX = 72.0 * 100.0 / 2.54;
    if( dpiY==0.0 )    dpiY = 72.0 * 100.0 / 2.54;

    sizeX = m_Zoom * 100.0 * 1000.0 * width  / dpiX;
    sizeY = m_Zoom * 100.0 * 1000.0 * height / dpiY;

    // stretched 
    ::StretchDIBits(pDC->m_hDC,
        // x-y-coord of destination upper-left corner
        sizeX, -sizeY,                       
        // width-height of destination rectangle
        (int)(sizeX+0.5), -(int)(sizeY+0.5), 
        // x-y-coord of source upper-left corner
        0, 0,                                
        // width-height of source rectangle
        (int)(width+0.5), (int)(height+0.5), 
        pData,                               // bitmap bits
        FreeImage_GetInfo(pDoc->m_handleFI),    // bitmap data
        DIB_RGB_COLORS,                      // usage options
        SRCCOPY                              // raster operation code
        );
}

.. or use (see code for how the parameters are to be initialized)

    // no stretching
    ::SetDIBitsToDevice(
        pDC->m_hDC, // handle to DC
        xDst, yDst, // x-y-coord of destination upper-left corner
        dxSrc, dySrc, // width-height of source rectangle
        xSrc, ySrc, // x-y-coord of source upper-left corner
        0,//uStartScan,// first scan line in array
        FreeImage_GetHeight(pFIBitmap), // number of scan lines
        FreeImage_GetBits(pFIBitmap), // array of DIB bits
        FreeImage_GetInfo(pFIBitmap), // bitmap information
        DIB_RGB_COLORS); // RGB or palette indexes

Image information

To complete the program, the relevant image information is shown in a dialog:

FreeImage

(Text taken from the freeimage-introduction ! )

What is freeimage ?

FreeImage is an Open Source library project for developers who would like to support popular graphics image formats like BMP, JPEG, TIFF and PCX and others as needed by today's multimedia applications. The libraries comes in two versions: a binary distribution that can be linked against any 32-bit c++ compiler and a source distribution. Workspace files for Microsoft Visual C++ 6 are provided, as well as makefiles for linux.

Features of freeimage

  • Ease of use. The library has been designed to be extremely simple in use. Our motto is: make difficult things simple instead of simple things difficult.
  • Not limited to the local PC. The unique FreeImageIO structure makes it possible to load your images from virtually anywhere. Possibilities include standalone files, memory, cabinet files and the Internet, all this without recompiling the library!
  • Plugin driven. The internal engine is made completely modular using a clever plugin system. Easily Write new plugins and store them in DLL files or embed the plugins directly into your application!
  • Color conversion. FreeImage provides many functions to convert a bitmap from one bitdepth to another.
  • Directly access bitmap bits and palette. Functions are provided which allow you to directly access the bitmap palette (if available) and bitmap bits.
  • Written in portable C++, should compile on all 32 bit Windows systems as well as under Linux and Solaris. Full source code provided.
  • Open Source Dual-License. You can choose the license that has the most advantages for you: Use the liberal FreeImage Public License to use FreeImage commercially or the GNU General Public License to use FreeImage into your open source project.
  • Easily integrates into DirectX and OpenGL. Only a minimum of programming is necessary to store a FreeImage bitmap into a DirectDraw surface. Or use FreeImage to load your Direct3D/OpenGL textures.
  • Provides many test programs to "show-off" the library.
  • Supports many formats, such as:
    • BMP files [reading, writing]
    • Dr. Halo files [reading] **
    • ICO files [reading]
    • IFF files [reading]
    • JBIG [reading, writing] *
    • JNG files [reading]
    • JPEG/JIF files [reading, writing]
    • KOALA files [reading]
    • LBM files [reading]
    • Kodak PhotoCD files [reading]
    • MNG files [reading]
    • PCX files [reading]
    • PBM files [reading, writing]
    • PGM files [reading, writing]
    • PNG files [reading, writing]
    • PPM files [reading, writing]
    • PhotoShop files [reading]
    • Sun RAS files [reading]
    • TARGA files [reading]
    • TIFF files [reading, writing]
    • WBMP files [reading, writing]

    * only via external plugin
    ** only grayscale

Freeimags-Internals

Freeimage loads the various file-formats using different libraries, e.g. libtiff or zlib. When loading a file, the data is converted internally using the structure BITMAPINFO from the Win32-API (even when it is compiled under linux). This approach makes it easy converting from format x to format y. To support a specific file-format there are needed only 2 converters, one for loading from the file to a BITMAPINFO and the other for saving from BITMAPINFO into the file:

FIBITMAP         *FreeImage_Load(FREE_IMAGE_FORMAT fif, 
                                 const char *filename, int flags);
BOOL              FreeImage_Save(FREE_IMAGE_FORMAT fif, FIBITMAP *dib, 
                                 const char *filename, int flags);
FREE_IMAGE_FORMAT FreeImage_GetFIFFromFilename(const char *filename);

If you need more infos, download the source, want to discuss or, even better, want to develop additional features, you can visit the freeimage homepage.

Some programming hints can be found here: FreeImage FAQ.

Credits

The code was written using:

freeimage freeimage-homepage
Vassili Bourdo code for the shell His homepage
Chris Maunder for the CDIBSectionLite-class

History

Version 1.0 25. Sept. 2001
  • Initial publication
Version 2.4.2 7. Oct. 2001
  • uses freeimage 2.4.2 (see changes)
  • wait-Cursor
  • exception-handling while loading
Version 2.5.1 14. March 2002
  • loading in background thread -> gui still usable when operation is long
  • using the ClipBox: transforming only the neccessary pixels from the buffer to the screen -> improved drawing-speed (much faster)
  • uses freeimage 2.5.1 (see changes)
Version 2.5.2 26. March 2002
  • uses freeimage 2.5.2 beta 1 (see changes)
  • mouseWheel = Zoom in/out
  • Progress shown in Statusbar while working in background-thread
  • multipage-support
Version 2.5.3 22. April 2002
  • uses freeimage 2.5.3 beta 1 (see changes)
  • fixed some problems loading gray-images and 16-bit tiff
  • sample showing opening an image from a resource (click on res)
  • integrated code for clipboard copy/paste
  • improved drawing:
    if image is not scaled: SetDIBitsToDevice(), otherwise StretchDIBits()
  • some minor fixes

Coming versions (maybe)

  • edit ontop of images
  • activeX Control
  • console für batch ?
  • I plan to continue the Graphics-Suite to display vector-data on top of the images. The vector-information is stored in SVG-files. For more info about SVG see w3c and abobe.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Markus Loibl
Germany Germany
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionSource code neededmembersaiful_vonair7 Sep '12 - 0:02 
Hi
 
Can you please give me the source code.
 
Thanks
Email: saiful_vonair@yahoo.com
Generalconversion image to 16 bitmembershekhar25839523 Jul '09 - 23:13 
How can we convert an JPG image in 16 bit image
GeneralBugmemberMember 390867112 Dec '08 - 1:58 
in void CGraphicSuiteView::OnDraw(CDC* pDC)
 
erg = pDC->GetClipBox(&clipRect);
 
if( erg==ERROR || erg==NULLREGION)
return;
 
pDC->SetMapMode(MM_HIMETRIC);
 
You need to set the map mode _before_ you get the clipbox, otherwise you'll be comparing dissimilar metrics.
GeneralBugmemberMember 390867112 Dec '08 - 1:56 
in void CGraphicSuiteView::CreateMyPalette()
 
LOGPALETTE PaletteInfo;
PaletteInfo.palNumEntries = count;

for (unsigned int i = 0; i < count; i++)
{
PaletteInfo.palPalEntry[i].peRed = pRgb[i].rgbRed;
PaletteInfo.palPalEntry[i].peGreen = pRgb[i].rgbGreen;
PaletteInfo.palPalEntry[i].peBlue = pRgb[i].rgbBlue;
PaletteInfo.palPalEntry[i].peFlags = 0;
}
 

in wingdi.h
 
typedef struct tagLOGPALETTE {
WORD palVersion;
WORD palNumEntries;
PALETTEENTRY palPalEntry[1];
} LOGPALETTE, *PLOGPALETTE, NEAR *NPLOGPALETTE, FAR *LPLOGPALETTE;
 
Only 1 Palette Entry is allocated in this struct : you will corrupt your stack.
you will need to allocate this struct with enough storage for the count.
Generalnice, thankmemberfuturejo13 Nov '08 - 2:51 
nice, thank
GeneralVery Nice Article but i have a questionmemberCold-Fire10 Aug '08 - 7:49 
How can I use your library such that I can trasform BMP to JPEG in memory??
 
I mean without loading a BMP file and saving to a JPEG file.
Suppose I have a HBITMAP in memory...and using just that I want to get the equivalent JPEG file data (in memory too) so that I can write it inside a ZIP on disk.
 
Right now I have to open a BMP...save it to JPEG...and add the JPEG to the ZIP...off course deleteing the BMP and JPEG afterwards....this works quite slow because there is a lot overhead on the harddisk. By doing it in memory (much faster) I will only do one operation (write) on the disk.
 
Thanks in advance for any suggestions Cool | :cool:
Generalif this project is compiled in vc6.0memberdamoqiuying2 Apr '08 - 17:44 
I use vs2005 to open the project.but when compiling ,there is something wrong.So i think if this project is build in VC6.0 . I want to know if there is some way I can open it with vs2005.
GeneralRe: if this project is compiled in vc6.0membervictoryli10 Apr '08 - 9:03 
I have the same problem. After I converted the project into VC2005 and tried to build it, I got the error message:
 
c:\graphicsuite_src\freeimage\freeimage.h(204) : error C2383: 'FI_AllocateProc' : default-arguments are not allowed on this symbol
 
Could the author have a look at this problem?
GeneralRe: if this project is compiled in vc6.0member9870182371 Feb '09 - 19:54 
seems that freeimage not working well under vs2005,
mail to flvdberg@wxs.nl, but the address is not exist.
GeneralRe: if this project is compiled in vc6.0member9870182372 Feb '09 - 0:30 
I solved it.
 
you can see freeimage.h, such as
 
// For C compatility --------------------------------------------------------
 
#ifdef __cplusplus
#define FI_DEFAULT(x) //= x
#define FI_ENUM(x) enum x
#define FI_STRUCT(x) struct x
#else
#define FI_DEFAULT(x)
#define FI_ENUM(x) typedef int x; enum x
#define FI_STRUCT(x) typedef struct x x; struct x
#endif
 
then, error c2383 not occured.
but 19 error will followed in PxShlAPI.CPP.
after correct them one by one, the graphicsuit running OK.
GeneralCouldn't run FreeImage example "fiptest" in VS 2005 in c++member00thilani27 Dec '07 - 21:01 
I'm using the FreeImage 3.10.0 libraries.
I compiled the FreeImage project and generated the FreeImage.lib FreeImaged.lib
Then I tried to run the "fiptest" program in C++.And I included above libraries to project.
But there are link errors comming

I can't find where I go wrong.

[Error List]
Error 59 error LNK2001: unresolved external symbol "private: static union half::uif const * const half::_toFloat" (?_toFloat@half@@0QBTuif@1@B) d:\Lerning\l4s2\downloaded\FreeImage3100Win32(2)\FreeImage\Wrapper\FreeImagePlus\test\FreeImaged.lib 1
Error 74 error LNK2001: unresolved external symbol "private: static unsigned short const * const half::_eLut" (?_eLut@half@@0QBGB) d:\Lerning\l4s2\downloaded\FreeImage3100Win32(2)\FreeImage\Wrapper\FreeImagePlus\test\FreeImaged.lib 1
Error 55 error LNK2001: unresolved external symbol "public: __thiscall Iex::BaseExc::BaseExc(class Iex::BaseExc const &)" (??0BaseExc@Iex@@QAE@ABV01@@Z) d:\Lerning\l4s2\downloaded\FreeImage3100Win32(2)\FreeImage\Wrapper\FreeImagePlus\test\FreeImaged.lib 1
Error 61 error LNK2001: unresolved external symbol "public: virtual bool __thiscall Imf::IStream::isMemoryMapped(void)const " (?isMemoryMapped@IStream@Imf@@UBE_NXZ) d:\Lerning\l4s2\downloaded\FreeImage3100Win32(2)\FreeImage\Wrapper\FreeImagePlus\test\FreeImaged.lib 1
Error 62 error LNK2001: unresolved external symbol "public: virtual char * __thiscall Imf::IStream::readMemoryMapped(int)" (?readMemoryMapped@IStream@Imf@@UAEPADH@Z) d:\Lerning\l4s2\downloaded\FreeImage3100Win32(2)\FreeImage\Wrapper\FreeImagePlus\test\FreeImaged.lib 1
Error 57 error LNK2001: unresolved external symbol "public: virtual char const * __thiscall Iex::BaseExc::what(void)const " (?what@BaseExc@Iex@@UBEPBDXZ) d:\Lerning\l4s2\downloaded\FreeImage3100Win32(2)\FreeImage\Wrapper\FreeImagePlus\test\FreeImaged.lib 1
Error 28 error LNK2001: unresolved external symbol _cio_tell d:\Lerning\l4s2\downloaded\FreeImage3100Win32(2)\FreeImage\Wrapper\FreeImagePlus\test\FreeImaged.lib 1
Error 12 error LNK2001: unresolved external symbol _opj_cio_close d:\Lerning\l4s2\downloaded\FreeImage
QuestionHow to configure FreeImage3100Win32member00thilani27 Dec '07 - 5:53 
I have downloaded the FreeImage 3.10.0 version It is for windows xp.But I can't run the
test(flip test) project included in the distribution.
I run the application in VS 2005.
 
get the error
fatal error LNK1181: cannot open input file 'FreeImaged.lib' fipTest
But I couldn't find a 'FreeImaged.lib' in the distribution.
 
Appreciate a Quick reply
 
regards
 
THilani
Questionhow can i add xxx.tiff to opened my.pdf documentmemberBAndrik19 Oct '07 - 0:00 
May be somebody wrote some code to set *.tif image on opened pdf file???
 
implementation on C++
AnswerRe: how can i add xxx.tiff to opened my.pdf documentmembersskhalsa9 Sep '08 - 18:29 
can u give me the knowledge of the tiff how to read the tiff image
GeneralRe: how can i add xxx.tiff to opened my.pdf documentmemberBAndrik10 Sep '08 - 22:22 
If really to say, i forgot already how i have done this.
There are some special functions
You can look for it in http://www.adobe.com/support/forums/
use search...
i'm sorry but i didn't remember. Now i have no access to that code
Generalnice, just what I need :)memberqiuqianren7 Oct '07 - 1:20 
nice, just what I need Smile | :)
GeneralRe: nice, just what I need :)membervictoryli10 Apr '08 - 8:57 
Did you download the source files and try to run it in VC2005 or VC6?
Generalconvert PNG to DIB and DIB to PNGmemberShlomo11 Apr '07 - 2:49 
Hi,
 
Great program Smile | :)
I want to use it to convert the DIB I receive from the screen with out the
need to save it as BMP and then load it with your program.
Same thing backwords, convert the PNG to DIB in memory.
Is there a way to do it?Sigh | :sigh:
Why don't you give the FreeImage.dll source code?
 

GeneralI cant load ur FreeImage.dllmemberchintan.desai27 Nov '06 - 20:23 
Hi.
I need to use this dll in my C#.NET Application.But while trying to add it in add reference.it generate error as "This is not valid COM file"
Help
GeneralRe: I cant load ur FreeImage.dllmemberNoEscom8 Jan '07 - 11:12 
FreeImage is not a COM file, but a standard DLL with c-style functions.
GeneralNice work but without LZW I can't use itmembertrifi22 Nov '06 - 22:17 
Nice work and I would use it but when I try to load LZW tif file I receive a message "LZW compression is no longer supported..."
Even if I want to ask just for the resolution or size of the file I can't.
In fact I have a Unisys license but can't work with the LZW files using the library.
Library should give the opportunity to load and open LZW files and the responsibility using files like this is for the user
Kind regards,

 
Trifon Alekov
GeneralRe: Nice work but without LZW I can't use itmemberNoEscom8 Jan '07 - 11:13 
Now that the LZW patent has expired, FreeImage can handle LZW compressed bitmaps again.
QuestionError C2383 on compilationmemberDeadave15 Aug '06 - 10:29 
Hi.
 
This is what I'm getting:
 
Error C2383 'symbol' : default-arguments are not allowed on this symbol.
 
Which refer to the FreeImage.h file at the line:
 
typedef FIBITMAP *(DLL_CALLCONV *FI_AllocateProc)(int width, int height, int bpp, unsigned red_mask FI_DEFAULT(0), unsigned green_mask FI_DEFAULT(0), unsigned blue_mask FI_DEFAULT(0));
 

I think that I understand the meaning of the error; I have to get rid of the default inisialization (0). I've tried that and it does not work. I've tried a few other things too, and no success.
 
What to do?
AnswerRe: Error C2383 on compilationmemberDeadave21 Aug '06 - 10:48 
Nevermind guys...I used VC++ 6 and did a release...working now.
Having alot of problems with .NET 2003 thou!!!
GeneralRe: Error C2383 on compilation [modified]memberfirehore_00730 Jun '11 - 4:19 
I have also the same problem!
I have Visual Studio 2010 Premium but it work only with VC6.
So i download WMware Player(freeware) and installier XP and VC6.

modified on Thursday, June 30, 2011 10:41 AM

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 2 May 2002
Article Copyright 2001 by Markus Loibl
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid