在向大家介紹CxImage類庫之前,先向大家推薦一個優秀的站點:
http://www.codeproject.com
。這個站點有很多值得收藏的文章和源碼。本文就是根據此站點相關信息寫成。
關于這個類,可以看CodeProject上的文章:http://www.codeproject.com/bitmap/CXImage.asp
CxImage是一個可以用于MFC的C++類,可以打開,保存,顯示,轉換各種格式的圖像文件,比如BMP, JPEG, GIF, PNG, TIFF, MNG, ICO, PCX, TGA, WMF, WBMP, JBG, J2K 等格式的文件。可以實現BMP<->JPG,PNG?<>TIFF格式等等的轉換。
它的作者是: Davide Pizzolato ,主頁: http://www.xdp.it/
CxImage類庫是一個優秀的圖像操作類庫。它可以快捷地存取、顯示、轉換各種圖像。有的讀者可能說,有那么多優秀的圖形庫,如OpenIL,FreeImage,PaintLib等等,它們可謂是功能強大,齊全,沒必要用其它的類庫。但我要說,這些類庫基本上沒有免費的,使用這些類庫,你要被這樣那樣的許可協議所束縛。在這點上,CxImage類庫是完全免費的。另外,在使用上述類庫時,你會遇到重重麻煩。因為它們大部分是平臺無關的,且用C語言寫成,有的還夾雜著基本的C++ wrapper和成堆德編譯選項的聲明需要你去處理。而CxImage類庫在這方面做得很好。還有讓我最看好的,就是作者完全公開了
源代碼
。相對于那些封裝好的圖形庫和GDI+來說,這一點使我們可以進一步學習各種編解碼技術,而不再浮于各種技術的表面。 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? ...
兼容性: - 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) 關于CxImage類庫作者: Davide Pizzolato,一位電子工程師。1984年開始編程,已不在乎使用何種編程語言來開發軟件。現就職于Askoll的電子研發部。
posted on 2006-09-10 21:07
Jerry Cat 閱讀(1287)
評論(0) 編輯 收藏 引用