在向大家介紹CxImage類庫(kù)之前,先向大家推薦一個(gè)優(yōu)秀的站點(diǎn):
http://www.codeproject.com
。這個(gè)站點(diǎn)有很多值得收藏的文章和源碼。本文就是根據(jù)此站點(diǎn)相關(guān)信息寫成。
關(guān)于這個(gè)類,可以看CodeProject上的文章:http://www.codeproject.com/bitmap/CXImage.asp
CxImage是一個(gè)可以用于MFC的C++類,可以打開,保存,顯示,轉(zhuǎn)換各種格式的圖像文件,比如BMP, JPEG, GIF, PNG, TIFF, MNG, ICO, PCX, TGA, WMF, WBMP, JBG, J2K 等格式的文件。可以實(shí)現(xiàn)BMP<->JPG,PNG?<>TIFF格式等等的轉(zhuǎn)換。
它的作者是: Davide Pizzolato ,主頁(yè): http://www.xdp.it/
CxImage類庫(kù)是一個(gè)優(yōu)秀的圖像操作類庫(kù)。它可以快捷地存取、顯示、轉(zhuǎn)換各種圖像。有的讀者可能說(shuō),有那么多優(yōu)秀的圖形庫(kù),如OpenIL,FreeImage,PaintLib等等,它們可謂是功能強(qiáng)大,齊全,沒(méi)必要用其它的類庫(kù)。但我要說(shuō),這些類庫(kù)基本上沒(méi)有免費(fèi)的,使用這些類庫(kù),你要被這樣那樣的許可協(xié)議所束縛。在這點(diǎn)上,CxImage類庫(kù)是完全免費(fèi)的。另外,在使用上述類庫(kù)時(shí),你會(huì)遇到重重麻煩。因?yàn)樗鼈兇蟛糠质瞧脚_(tái)無(wú)關(guān)的,且用C語(yǔ)言寫成,有的還夾雜著基本的C++ wrapper和成堆德編譯選項(xiàng)的聲明需要你去處理。而CxImage類庫(kù)在這方面做得很好。還有讓我最看好的,就是作者完全公開了
源代碼
。相對(duì)于那些封裝好的圖形庫(kù)和GDI+來(lái)說(shuō),這一點(diǎn)使我們可以進(jìn)一步學(xué)習(xí)各種編解碼技術(shù),而不再浮于各種技術(shù)的表面。 CxImage類庫(kù)的結(jié)構(gòu):
一個(gè)CxImage對(duì)象是一個(gè)擴(kuò)展了的位圖。作者只是在位圖結(jié)構(gòu)上添加了一些起存儲(chǔ)信息作用的成員變量。一個(gè)CxImage對(duì)象(同時(shí))也是一組層。每個(gè)層只有在需要時(shí)才會(huì)分配相應(yīng)的緩沖區(qū)。CxImage::pDib代表著背景圖像,CxImage::pAlpha代表著透明層,CxImage::pSelection代表著被選中的層,被用來(lái)創(chuàng)建圖像處理時(shí)讓用戶感興趣的區(qū)域。在這三個(gè)特殊層面的基礎(chǔ)上,你可以增加一些額外的層,這些層可以存儲(chǔ)在CxImage::pLayers中。一般說(shuō)來(lái),層是一個(gè)完整的CxImage對(duì)象。因此,你可以構(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
];?
//
出錯(cuò)信息
????
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í)際的幀數(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;???
//
一些編碼選項(xiàng)
RGBQUAD?last_c;???????????
//
一些優(yōu)化選項(xiàng)
????BYTE????last_c_index;
????
bool
????last_c_isvalid;
????
long
????nNumLayers;
????DWORD???dwFlags;
}
?CXIMAGEINFO;
?
要在picture box中顯示一個(gè)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();
?
需要大家注意的是:整個(gè)CxImage類庫(kù)非常大。如果你只需要能處理其中的幾種格式,你可以在主要的頭文件ximage.h中找到一些開關(guān)選項(xiàng)來(lái)關(guān)閉一些圖像庫(kù)。JPG、PNG、TIFF中的每一個(gè)庫(kù),都會(huì)向最終程序增加約100KB的內(nèi)容。而CxImage類庫(kù)壓縮后只有約60KB。所以,你需要謹(jǐn)慎挑選一些你真正需要的類庫(kù)。作者提供的示例工程在編譯后,你會(huì)發(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)幾分鐘的時(shí)間(中間文件可達(dá)60MB)。下面則是使用CxImage類庫(kù)前必須設(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) 關(guān)于CxImage類庫(kù)作者: Davide Pizzolato,一位電子工程師。1984年開始編程,已不在乎使用何種編程語(yǔ)言來(lái)開發(fā)軟件。現(xiàn)就職于Askoll的電子研發(fā)部。
posted on 2006-09-10 21:07
Jerry Cat 閱讀(1286)
評(píng)論(0) 編輯 收藏 引用