|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
PrefaceYears after the previous version, I can tell that the article has survived its author, and even if my opinion on the limits of this library has not changed, an update was really necessary. Thank you very much to all the people that gave their contribution to this new release, with hundreds of small and big enhancements, my role was mainly to put all the pieces together. Introduction & License
The class
What's New in Version 6.00The complete list of bugfixes and enhancements is reported in the documentation, (see \doc\cximage_history.htm, or this link). Here I will highlight some of the new features. An application written with The applications linked with the old DLL will not work with the new one; but if necessary you can edit the declarations, or add new overloads, and revert to the old interface for the DLL. An issue to take care is File Formats & Linked C Libraries
The j2k library (now openjpeg), and the associated class
The next table shows the different amount of artifacts in the compressed image, using to different subsampling. 4:4:4 subsampling is useful in images with sharp edges, to reduce the typical blurring effect of the JPG compression.
PortabilityThe class and the projects have been tested with different compilers, from Microsoft VC++6 to VC++2008, with Borland C++ Builder 3 and 6, and partially with wxDev-C++ and MinGW. UNICODE and non-UNICODE configurations are provided for all the libraries (thanks to Eric Jesover). A light version (cximage600_lite) without the C libraries and with a small demo is provided for the first time users, or as a basic template, without the clutter of the full demo project. The console (\demo2) and the CxImageCrtDll projects can be built with VC++Express2005 and the Microsoft Platform SDK. If you get linker errors like "unresolved external...", check if all the C libraries have been compiled (set the correct project dependencies), or add the gdi32.lib and user32.lib modules to the Linker\Input\Additional Dependencies property.
The compatibility between little-endian and big-endian platforms, for the built in formats (bmp, ico, tga, pcx, gif, ska) is handled by DemoAlmost all the new features can be tested in the main
CxImage StructureIn the vertical hierarchy of the library, The glue to connect all the modules and the C libraries is
A class CxImage { ... protected: void* pDib; //contains the header, the palette, the pixels BITMAPINFOHEADER head; //standard header CXIMAGEINFO info; //extended information BYTE* pSelection; //selected region BYTE* pAlpha; //alpha channel CxImage** ppLayers; //generic layers CxImage** ppFrames; //frames for animation }
typedef struct tagCxImageInfo { DWORD dwEffWidth; //DWORD aligned scan line width BYTE* pImage; //THE IMAGE BITS void* pGhost; //if this is a ghost, pGhost point to the body DWORD dwType; //original image format char szLastError[256]; //debugging long nProgress; //monitor long nEscape; //escape long nBkgndIndex; //used for GIF, PNG, MNG RGBQUAD nBkgndColor; //used for RGB transparency BYTE nQuality; //used for JPEG long nFrame; //used for TIF, GIF, MNG : actual frame long nNumFrames; //used for TIF, GIF, MNG : total number of //frames DWORD dwFrameDelay; //used for GIF, MNG long xDPI; //horizontal resolution long yDPI; //vertical resolution RECT rSelectionBox; //bounding rectangle BYTE nAlphaMax; //max opacity (fade) bool bAlphaPaletteEnabled; //true if alpha values in the palette are // enabled. bool bEnabled; //enables the painting functions long xOffset; long yOffset; DWORD dwEncodeOption; //for GIF, TIF : 0=def.1=unc,2=fax3,3=fax4, // 4=pack,5=jpg RGBQUAD last_c; //for GetNearestIndex optimization BYTE last_c_index; bool last_c_isvalid; long nNumLayers; DWORD dwFlags; } CXIMAGEINFO;
CxImage Class Members & OperationsCxImage is documented using Doxygen , however for historical reasons, many uncommon features are still undocumented. The class members reference, together with release history, and license, can be found here Supported Formats and OptionsThe whole library is quite big, in the main header file ximcfg.h you'll find the switches to enable or disable a specific graphic format or feature. Each JPG, PNG and TIFF library adds about 100KB to the final application, while the
Using CxImage in your Projects
To use CxImage in your project, you must edit these settings: Project Settings
|- C/C++
| |- Code Generation
| | |- Use run-time library : Multithreaded DLL (must be the same for
| | | all the linked libraries)
| | |- Struct member alignment : must be the same for all the linked
| | | libraries
| |- Precompiled headers : not using precompiled headers
| |- Preprocessor
| |- Additional Include Directories: ..\cximage
|- Link
|- General
|- Object/library modules: ../png/Debug/png.lib
../raw/Debug/libdcr.lib
../jpeg/Debug/jpeg.lib
../zlib/Debug/zlib.lib
../tiff/Debug/tiff.lib
../jasper/Debug/jasper.lib
../cximage/Debug/cximage.lib ...
In your source code you must add Note: don't mix debug and release modules; each configuration must use its respective library modules. Adding your Custom Functions in CxImageWriting a new function for image processing is not so hard with bool CxImage::Jitter(long radius)
{
// check if the image is valid, this should be always the first line in
// the function
if (!pDib) return false;
// local variables
long nx,ny;
// temporary image to store the partial results of the algorithm
CxImage tmp(*this,pSelection!=0,true,true);
// limit the effects of the functions only in the smallest rectangle that
// holds the selected region (defined with the Selection...() functions ),
// this will speed up the loops.
long xmin,xmax,ymin,ymax;
if (pSelection){
xmin = info.rSelectionBox.left; xmax = info.rSelectionBox.right;
ymin = info.rSelectionBox.bottom; ymax = info.rSelectionBox.top;
} else {
xmin = ymin = 0;
xmax = head.biWidth; ymax=head.biHeight;
}
// main loop : scan the image in vertical direction
for(long y=ymin; y <ymax; y++){
// monitor the progress of the loops
info.nProgress = (long)(100*y/head.biHeight);
// let the application a way to exit quickly
if (info.nEscape) break;
// main loop : scan the image in horizontal direction
for(long x=xmin; x<xmax; x++){
// if the feature is enabled, process only the pixels inside the
// selected region
#if CXIMAGE_SUPPORT_SELECTION
if (SelectionIsInside(x,y))
#endif //CXIMAGE_SUPPORT_SELECTION
{
// main algorithm
nx=x+(long)((rand()/(float)RAND_MAX - 0.5)*(radius*2));
ny=y+(long)((rand()/(float)RAND_MAX - 0.5)*(radius*2));
if (!IsInside(nx,ny)) {
nx=x;
ny=y;
}
// save the result in the temporary image.
// if you can, use PixelColor only for 24 bpp images,
// and PixelIndex for 8, 4 and 1 bpp images : it's faster
if (head.biClrUsed==0){
tmp.SetPixelColor(x,y,GetPixelColor(nx,ny));
} else {
tmp.SetPixelIndex(x,y,GetPixelIndex(nx,ny));
}
// if the feature is enabled, process also the pixels
// in the alpha layer
#if CXIMAGE_SUPPORT_ALPHA
tmp.AlphaSet(x,y,AlphaGet(nx,ny));
#endif //CXIMAGE_SUPPORT_ALPHA
}
}
}
// save the result and exit
Transfer(tmp);
return true;
}
Examples: How to ...... Convert from One Format to AnotherCxImage image;
// bmp -> jpg
image.Load("image.bmp", CXIMAGE_FORMAT_BMP);
if (image.IsValid()){
if(!image.IsGrayScale()) image.IncreaseBpp(24);
image.SetJpegQuality(80);
image.Save("image.jpg",CXIMAGE_FORMAT_JPG);
}
// png -> tif
image.Load("image.png", CXIMAGE_FORMAT_PNG);
if (image.IsValid()){
image.Save("image.tif",CXIMAGE_FORMAT_TIF);
}
... Load an Image Resource//Load the resource IDR_PNG1 from the PNG resource type
CxImage* newImage = new CxImage();
newImage->LoadResource(FindResource(NULL,MAKEINTRESOURCE(IDR_PNG1),
"PNG"),CXIMAGE_FORMAT_PNG);
or
//Load the resource IDR_JPG1 from DLL
CxImage* newImage = new CxImage();
HINSTANCE hdll=LoadLibrary("imagelib.dll");
if (hdll){
HRSRC hres=FindResource(hdll,MAKEINTRESOURCE(IDR_JPG1),"JPG");
newImage->LoadResource(hres,CXIMAGE_FORMAT_JPG,hdll);
FreeLibrary(hdll);
}
or
//Load a bitmap resource;
HBITMAP bitmap = ::LoadBitmap(AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDB_BITMAP1)));
CxImage *newImage = new CxImage();
newImage->CreateFromHBITMAP(bitmap);
... Decode an Image from MemoryCxImage image((BYTE*)buffer,size,image_type);
or
CxMemFile memfile((BYTE*)buffer,size);
CxImage image(&memfile,image_type);
or
CxMemFile memfile((BYTE*)buffer,size);
CxImage* image = new CxImage();
image->Decode(&memfile,type);
... Encode an Image in Memorylong size=0;
BYTE* buffer=0;
image.Encode(buffer,size,image_type);
...
image.FreeMemory(buffer);
or
CxMemFile memfile; memfile.Open(); image.Encode(&memfile,image_type); BYTE* buffer = memfile.GetBuffer(); long size = memfile.Size(); ... image.FreeMemory(buffer); ... Create a Multipage TIFFCxImage *pimage[3];
pimage[0]=&image1;
pimage[1]=&image2;
pimage[2]=&image3;
FILE* hFile;
hFile = fopen("multipage.tif","w+b");
CxImageTIF multiimage;
multiimage.Encode(hFile,pimage,3);
fclose(hFile);
or
FILE* hFile;
hFile = fopen("c:\\multi.tif","w+b");
CxImageTIF image;
image.Load("c:\\1.tif",CXIMAGE_FORMAT_TIF);
image.Encode(hFile,true);
image.Load("c:\\2.bmp",CXIMAGE_FORMAT_BMP);
image.Encode(hFile,true);
image.Load("c:\\3.png",CXIMAGE_FORMAT_PNG);
image.Encode(hFile);
fclose(hFile);
... Copy/Paste an Image//copy
HANDLE hDIB = image->CopyToHandle();
if (::OpenClipboard(AfxGetApp()->m_pMainWnd->GetSafeHwnd())) {
if(::EmptyClipboard()) {
if (::SetClipboardData(CF_DIB,hDIB) == NULL ) {
AfxMessageBox( "Unable to set Clipboard data" );
} } }
CloseClipboard();
//paste
HANDLE hBitmap=NULL;
CxImage *newima = new CxImage();
if (OpenClipboard()) hBitmap=GetClipboardData(CF_DIB);
if (hBitmap) newima->CreateFromHANDLE(hBitmap);
CloseClipboard();
... Display a File in a Picture BoxHBITMAP m_bitmap = NULL;
CxImage image("myfile.png", CXIMAGE_FORMAT_PNG);
...
CDC* hdc = m_picture.GetDC();
HBITMAP m_bitmap = image.MakeBitmap(hdc->m_hDC);
HBITMAP hOldBmp = m_picture.SetBitmap(m_bitmap);
if (hOldBmp) DeleteObject(hOldBmp);
if (hdc->m_hDC) m_picture.ReleaseDC(hdc);
...
if (m_bitmap) DeleteObject(m_bitmap);
History and CreditsStarting form my With
More specific credits and disclaimers are in every header file of each library. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||