[翻译]
Davide Pizzolato.著CxImage
[简介]
CxImage 是一个C++类,可以加载、保存、显示,转换BMP, JPEG, GIF, PNG, TIFF, MNG, ICO, PCX, TGA, WMF, WBMP, JBG, J2K 等格式图像。
[程序结构]
Cximage以位图为基础,并附加一些信息保存信息。
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** pLayers; //generic layers
}
CxImage::head 是一个位图头,CxImage::pDib 是通常的位图。CxImage::info 是一个存储在不同格式之间的许多共享信息。
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对象还是多层的集合。每层的缓冲只在必要的时候才被分配。
CxImage::pDib是背景图,CxImage::pAlpha 是透明层,CxImage::pSelection 是选择层,用于创建图像处理的区域。在这三层外,你还可以定义,然后存储在CxImage::pLayers中。
CxImage类成员和操作
支持的格式和操作
[使用CxImage]
要想使用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 ...
[使用实例]
转换图像格式
// 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);
}
加载图像资源
CxImage* newImage = new CxImage();
newImage->LoadResource(FindResource(NULL,MAKEINTRESOURCE(IDR_PNG1),
"PNG"),CXIMAGE_FORMAT_PNG);
or
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
HBITMAP bitmap = ::LoadBitmap(AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDB_BITMAP1)));
CxImage *newImage = new CxImage();
newImage->CreateFromHBITMAP(bitmap);
解码内存中的图像
or
CxImage image(&memfile,image_type);
or
CxImage* image = new CxImage();
image->Decode(&memfile,type);
编码内存中的图像
BYTE* buffer=0;
image.Encode(buffer,size,image_type);
...
free(buffer);
or
memfile.Open();
image.Encode(&memfile,image_type);
BYTE* buffer = memfile.GetBuffer();
long size = memfile.Size();
...
free(buffer);
创建一个多页的TIFF
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
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);
拷贝粘贴图像
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();
在picture框中显示图像文件
CxImage image("myfile.png", CXIMAGE_FORMAT_PNG);
...
m_bitmap = image.MakeBitmap(m_picture.GetDC()->m_hDC);
m_picture.SetBitmap(m_bitmap);
...
if (m_bitmap) DeleteObject(m_bitmap);