CxImage類庫是一個優(yōu)秀的圖像操作類庫。

外文名

CxImage

特點(diǎn)

快捷地存取、顯示、轉(zhuǎn)換各種圖像

概念

CxImage類庫是一個優(yōu)秀的圖像操作類庫。它可以快捷地存取、顯示、轉(zhuǎn)換各種圖像。有的讀者可能說,有那么多優(yōu)秀的圖形庫,如OpenIL,FreeImage,PaintLib等等,它們可謂是功能強(qiáng)大,齊全,沒必要用其它的類庫。但我要說,這些類庫基本上沒有免費(fèi)的,使用這些類庫,你要被這樣那樣的許可協(xié)議所束縛。在這點(diǎn)上,CxImage類庫是完全免費(fèi)的。另外,在使用上述類庫時,你會遇到重重麻煩。因為它們大部分是平臺無關(guān)的,且用C語言寫成,有的還夾雜著基本的C++ wrapper和成堆的編譯選項的聲明需要你去處理。而CxImage類庫在這方面做得很好。還有讓我最看好的,就是作者完全公開了源代碼。相對于那些封裝好的圖形庫和GDI+來說,這一點(diǎn)使我們可以進(jìn)一步學(xué)習(xí)各種編解碼技術(shù),而不再浮于各種技術(shù)的表面。

介紹

一個CxImage對象是一個擴(kuò)展了的位圖。作者只是在位圖結(jié)構(gòu)上添加了一些起存儲信息作用的成員變量。一個CxImage對象(同時)也是一組層。每個層只有在需要時才會分配相應(yīng)的緩沖區(qū)。CxImage::pDib代表著背景圖像,CxImage::pAlpha代表著透明層,CxImage::pSelection代表著被選中的層,被用來創(chuàng)建圖像處理時讓用戶感興趣的區(qū)域。在這三個特殊層面的基礎(chǔ)上,你可以增加一些額外的層,這些層可以存儲在CxImage::pLayers中。一般說來,層是一個完整的CxImage對象。因此,你可以構(gòu)造很復(fù)雜的嵌套層。下面是CxImage的一些成員變量:

class CxImage

{

...

protected:

void* pDib; //包含文件頭,調(diào)色板等等

BITMAPINFOHEADER head; //標(biāo)準(zhǔn)的文件頭(位圖)

CXIMAGEINFO info; //擴(kuò)展了的信息

BYTE* pSelection; //用戶選中的區(qū)域

BYTE* pAlpha; //alpha通道

CxImage** pLayers; //通用層

}

typedef struct tagCxImageInfo {

DWORD dwEffWidth; //DWORD 掃描線寬

BYTE* pImage; //圖像位數(shù)

void* pGhost; //if this is a ghost, pGhost point to the body

DWORD dwType; //原圖像的格式

char szLastError[256]; //出錯信息

long nProgress; //監(jiān)視循環(huán)的次數(shù)

long nEscape; //跳出標(biāo)志

long nBkgndIndex; //GIF, PNG, MNG格式使用

RGBQUAD nBkgndColor; //RGB三原色透明度

BYTE nQuality; //JPEG格式使用

long nFrame; //TIF, GIF, MNG使用 :實際的幀數(shù)

long nNumFrames; //TIF, GIF, MNG使用 :幀總數(shù)

DWORD dwFrameDelay; //GIF, MNG使用

long xDPI; //水平分辨率

long yDPI; //垂直分辨率

RECT rSelectionBox; //選中的矩形區(qū)

BYTE nAlphaMax; //陰影的最大不透明度

bool bAlphaPaletteEnabled; //如果調(diào)色板中有Alpha通道則為真

bool bEnabled; //打開繪圖函數(shù)

long xOffset;

long yOffset;

DWORD dwEncodeOption; //一些編碼選項

RGBQUAD last_c; //一些優(yōu)化選項

BYTE last_c_index;

bool last_c_isvalid;

long nNumLayers;

DWORD dwFlags;

} CXIMAGEINFO;

要在picture box中顯示一個png格式的文件,只需:

CxImage image("myfile.png", CXIMAGE_FORMAT_PNG);

HBITMAP m_bitmap = image.MakeBitmap(m_picture.GetDC()->m_hDC);

m_picture.SetBitmap(m_bitmap);

其它格式則類推。

Examples: how to ...

... convert from a format to another

CxImage image;

// bmp -> jpg

image.Load("image.bmp", CXIMAGE_FORMAT_BMP);

if (image.IsValid()){

if(!image.IsGrayScale()) image.IncreaseBpp(24);

image.SetJpegQuality(99);

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 memory

CxImage image((BYTE*)buffer,size,image_type);

orCxMemFile memfile((BYTE*)buffer,size);

CxImage image(&memfile,image_type);

orCxMemFile memfile((BYTE*)buffer,size);

CxImage* image = new CxImage();

image->Decode(&memfile,type);

... encode an image in memory

long size=0;

BYTE* buffer=0;

image.Encode(buffer,size,image_type);

...

free(buffer);

orCxMemFile memfile;

memfile.Open();

image.Encode(&memfile,image_type);

BYTE* buffer = memfile.GetBuffer();

long size = memfile.Size();

...

free(buffer);

... create a multipage TIFF

CxImage *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);

orFILE* 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();

需要大家注意的是:整個CxImage類庫非常大。如果你只需要能處理其中的幾種格式,你可以在主要的頭文件ximage.h中找到一些開關(guān)選項來關(guān)閉一些圖像庫。JPG、PNG、TIFF中的每一個庫,都會向最終程序增加約100KB的內(nèi)容。而CxImage類庫壓縮后只有約60KB。所以,你需要謹(jǐn)慎挑選一些你真正需要的類庫。作者提供的示例工程在編譯后,你會發(fā)現(xiàn)如下一些文件: ·CxImage : cximage.lib - static library

·CxImageCrtDll : cximagecrt.dll - DLL not using mfc

·CxImageMfcDll : cximage.dll - DLL using mfc

·Demo : demo.exe - program linked with cximage.lib and the C libraries

·DemoDll : demodll.exe - program linked with cximagecrt.dll

·j2k,jasper,jbig,jpeg,png,tiff,zlib : static C libraries

構(gòu)建這些工程需要耗費(fèi)幾分鐘的時間(中間文件可達(dá)60MB)。下面則是使用CxImage類庫前必須設(shè)置的一些參數(shù):

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

../jpeg/Debug/jpeg.lib

../zlib/Debug/zlib.lib

../tiff/Debug/tiff.lib

../cximage/Debug/cximage.lib ...

兼容性: - Microsoft Visual C++ 6.0 (static library, DLL and OCX builds) - Microsoft Visual C++ .NET 2003 - Borland C++ Builder version 3 and version 6 - Kdevelop 2.1 with gcc 2.96 (Linux)