close

CxImage類庫是一個優秀的圖像操作類庫。它可以快捷地存取、顯示、轉換各種圖像。有的讀者可能說,有那麼多優秀的圖形庫,如OpenIL,FreeImage,PaintLib等等,它們可謂是功能強大,齊全,沒必要用其它的類庫。但我要說,這些類庫基本上沒有免費的,使用這些類庫,你要被這樣那樣的許可協議所束縛。在這點上,CxImage類庫是完全免費的。另外,在使用上述類庫時,你會遇到重重麻煩。因為它們大部分是平台無關的,且用C語言寫成,有的還夾雜著基本的C++ wrapper和成堆德編譯選項的聲明需要你去處理。而CxImage類庫在這方面做得很好。還有讓我最看好的,就是作者完全公開了源代碼。相對於那些封裝好的圖形庫和GDI+來說,這一點使我們可以進一步學習各種編解碼技術,而不再浮於各種技術的表面。如果想下載CxImage,可以http://www.codeproject.com上下載。 CxImage類庫的架構︰




一個CxImage對象是一個擴展了的位圖。作者只是在位圖架構上添加了一些起存儲訊息作用的成員變量。一個CxImage對象(同時)也是一組層。每個層只有在需要時才會分發相應的緩沖區。CxImage::pDib代表著背景圖像,CxImage::pAlpha代表著透明層,CxImage::pSelection代表著被選中的層,被用來創建圖像處理時讓用戶感興趣的區域。在這三個特殊層面的基礎上,你可以增加一些額外的層,這些層可以存儲在CxImage::pLayers中。一般說來,層是一個完整的CxImage對象。因此,你可以構造很複雜的巢狀層。下面是CxImage的一些成員變量:




class CxImage
{
...
protected:
void* pDib;            //包含檔案頭,調色板等等
BITMAPINFOHEADER head; //標準的檔案頭(位圖)
CXIMAGEINFO info;      //擴展了的訊息
BYTE* pSelection;      //用戶選中的區域
BYTE* pAlpha;          //alpha通道
CxImage** pLayers;     //通用層
}
typedef struct tagCxImageInfo {
DWORD   dwEffWidth;       //DWORD 掃描線寬
BYTE*   pImage;           //圖像位數
void*   pGhost;           //if this is a ghost, pGhost point to the body
DWORD   dwType;           //原圖像的格式
char    szLastError[256]; //出錯訊息
long    nProgress;        //監視循環的次數
long    nEscape;          //跳出標誌
long    nBkgndIndex;      //GIF, PNG, MNG格式使用
RGBQUAD nBkgndColor;      //RGB三原色透明度
BYTE    nQuality;         //JPEG格式使用
long    nFrame;           //TIF, GIF, MNG使用 :實際的幀數
long    nNumFrames;       //TIF, GIF, MNG使用 :幀總數
DWORD   dwFrameDelay;     //GIF, MNG使用
long    xDPI;             //水準分辨率
long    yDPI;             //垂直分辨率
RECT    rSelectionBox;    //選中的矩形區
BYTE    nAlphaMax;        //陰影的最大不透明度
bool    bAlphaPaletteEnabled;  //如果調色板中有Alpha通道則為真
bool    bEnabled;         //打開繪圖函數
long    xOffset;
long    yOffset;
DWORD   dwEncodeOption;   //一些編碼選項
RGBQUAD last_c;           //一些優化選項
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中找到一些開關選項來關閉一些圖像庫。JPG、PNG、TIFF中的每一個庫,都會向最終程式增加約100KB的內容。而CxImage類庫壓縮後只有約60KB。所以,你需要謹慎挑選一些你真正需要的類庫。作者提供的示例工程在編譯後,你會發現如下一些檔案: ·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 構建這些工程需要耗費幾分鐘的時間(中間檔案可達60MB)。下面則是使用CxImage類庫前必須設定的一些參數︰




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  ...
arrow
arrow
    全站熱搜

    立你斯 發表在 痞客邦 留言(0) 人氣()