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,
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;
::StretchDIBits(pDC->m_hDC,
sizeX, -sizeY,
(int)(sizeX+0.5), -(int)(sizeY+0.5),
0, 0,
(int)(width+0.5), (int)(height+0.5),
pData,
FreeImage_GetInfo(pDoc->m_handleFI),
DIB_RGB_COLORS,
SRCCOPY
);
}
.. or use (see code for how the parameters are to be initialized)
::SetDIBitsToDevice(
pDC->m_hDC,
xDst, yDst,
dxSrc, dySrc,
xSrc, ySrc,
0,
FreeImage_GetHeight(pFIBitmap),
FreeImage_GetBits(pFIBitmap),
FreeImage_GetInfo(pFIBitmap),
DIB_RGB_COLORS);
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
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:
History
Version 1.0 | 25. Sept. 2001 |
|
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.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.