配置環境
1、拷貝CxImage到項目目錄
- 編譯CxImage
- cximage600_full\CxImage:所有的頭文件和源文件
- 查找所有的lib
2、添加頭文件目錄
CxImage\Include
3、添加庫文件目錄
CxImage\lib
4、添加鏈接
cximage.lib
demod.lib
j2k.lib
jasper.lib
jbig.lib
jpeg.lib
png.lib
tiff.lib
zlib.lib
5、程序中添加頭文件
#include "ximage.h"
基本用法
打開圖像
CxImage image;
if(image.load("name", 類型)){
CDC *pDC = GetDC();
image.Draw(pDC->GetSafeHDC(),CRectrect(0,0,100,100));
pDC->DeleteDC;
}
旋轉
CxImage smallImage;//旋轉後的圖片
image.Rotate(90,&smallImage);//旋轉90,並且保存到smallImage中
smallImage.Save(保存的名字,類型);
鏡像
CxImage ImgTmp = image;
if(ImgTmp.Mirror()){
image.Draw(...., .....);
}
縮放
CxImage samllImg;
image.Resample(新寬度,新高度,0,&smallImg);
smallImg.Save("自定第一大小.jpg",CXIMAGE_SUPPORT_JPG);
剪輯
CDC *pDC=GetDC();
UpdateData();
CxImage smallImg;
tempimage.Crop(CRect(m_xTop,m_yTop,m_xWidth,m_yHeiht),&smallImg);
smallImg.Save("剪輯圖片.jpg",CXIMAGE_SUPPORT_JPG);
smallImg.Draw(pDC->GetSafeHdc(),CRect(40,70,picwidth,picheight));
pDC->DeleteDC();
混合
CDC *pDC=GetDC();
CxImage smallImg;
smallImg.Load("混合源文件.jpg",CXIMAGE_SUPPORT_JPG);
tempimage.Mix(smallImg,CxImageOpAvg,0,0,true);
tempimage.Save("Mix混合.jpg",CXIMAGE_SUPPORT_JPG);
tempimage.Draw(pDC->GetSafeHdc(),CRect(40,70,picwidth,picheight));
提示:因爲代碼是我臨時敲上去的,所以並不是通過編譯的源代碼,不過這裏也只是指出CxImage的基本用法,學習方法不要複製粘貼,動手敲的纔是屬於你自己的。
編譯CxImage類庫相關說明
作者提供的工程文件CxImgLib.dsw (VC++6.0)非常大。如果你只需要能處理其中的幾種格式,編譯該類庫時,你可以在配置的頭文件ximcfg.h 中找到一些編譯開關選項來關閉一些圖像庫。JPG、PNG、TIFF中的每一個庫,都會向最終程序增加約100KB的內容。
而CxImage類庫壓縮後只有約60KB。所以,你需要謹慎挑選一些你真正需要的類庫。
//類庫配置文件:ximacfg.h
#define CXIMAGE_SUPPORT_JPG 1
//如果要實現bmp->jpg 則必須打開
#define CXIMAGE_SUPPORT_BMP 1
#define CXIMAGE_SUPPORT_GIF 1
#define CXIMAGE_SUPPORT_JPG 1
//以上爲必須打開,下面的隨便
#define CXIMAGE_SUPPORT_PNG 0//不使用它
#define CXIMAGE_SUPPORT_MNG 0
#define CXIMAGE_SUPPORT_ICO 1
#define CXIMAGE_SUPPORT_TIF 0//
#define CXIMAGE_SUPPORT_TGA 0//
#define CXIMAGE_SUPPORT_PCX 0//
#define CXIMAGE_SUPPORT_WBMP 0//
#define CXIMAGE_SUPPORT_WMF 0//
#define CXIMAGE_SUPPORT_J2K 0 // Beta, use JP2
#define CXIMAGE_SUPPORT_JBG 0
//.............
各工程的作用對應如下:
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類庫進行圖像類型轉換,在你的VC工程中使用這個類庫,要對工程進行如下設置(Project Settings):
|- C/C++
| |- Code Generation
| | |- Use run-time library : Multithreaded DLL (must be the same for
| | | all the linked libraries) //應該只要是多線程DLL即可,DEBUG的也行
| | |- Struct member alignment : must be the same for all the linked libraries
| |- Precompiled headers : not using precompiled headers
| |- Preprocessor
| |- Additional Include Directories: ..\cximage
該處填CxImage裏的.h和.cpp文件拷貝並導入工程後所在的文件夾,填寫後在工程中include時編譯器會查找該文件夾,故include的文件無需路徑)
|- Link
|- General
|- Object/library modules: png.lib
jpeg.lib
zlib.lib
tiff.lib
jasper.lib
cximage.lib
把需要的lib文件從CxImage中拷貝到工程中的lib文件所在的目錄)
並且從CxImage中將xfile.h、ximacfg.h、ximadef.h、ximage.cpp、ximage.h、xiofile.h、 xmemfile.cpp、xmemfile.h拷貝到工程文件夾下並將CxImage.h文件加入工程中即可。也可以設置vc6的”tools”中的 “include”路徑.
下面介紹應用它進行圖像類型轉換的方式:
1.從一種圖像文件類型轉換爲另一種文件類型(convert from a format to another)
CxImage image; // 定義一個CxImage對象
// 從bmp文件轉換爲jpg文件(bmp -> jpg)
image.Load("image.bmp", CXIMAGE_FORMAT_BMP); //先裝載bmp文件,需要指定文件類型
// 判斷加載的bmp文件是否存在。
if (image.IsValid())......{
// Returns true if the image has 256 colors and a linear grey scale palette.
if(!image.IsGrayScale()) image.IncreaseBpp(24); // param nbit: 4, 8, 24
image.SetJpegQuality(99); // 設置圖像的壓縮質量參數(從0到100,數值越大,質量越高)
image.Save("image.jpg",CXIMAGE_FORMAT_JPG); // 把壓縮後的圖像以jpg文件類型保存起來。
}
// 從png文件轉換爲tif文件(png -> tif)
image.Load("image.png", CXIMAGE_FORMAT_PNG);
if (image.IsValid())...{
image.Save("image.tif",CXIMAGE_FORMAT_TIF);
}
2.加載程序資源圖像(load an image resource)
即從程序的資源圖像中構建CxImage對象,有如下幾種方式:
// 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);
或者
//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);
}
或者
//Load a bitmap resource;
HBITMAP bitmap = ::LoadBitmap(AfxGetInstanceHandle(),
MAKEINTRESOURCE(IDB_BITMAP1)));
CxImage *newImage = new CxImage();
newImage->CreateFromHBITMAP(bitmap);
3.在內存緩衝中的圖像類型轉換
A.把內存緩衝中的數據解碼成一個Image對象(decode an image from memory),有如下幾種方式:
CxImage image((BYTE*)buffer,size,image_type);//把內存緩衝buffer中的數據構造成Image對象
//或:
CxMemFile memfile((BYTE*)buffer,size); // 顯式使用CxMemFile對象
CxImage image(&memfile,image_type);
//或:
CxMemFile memfile((BYTE*)buffer,size);
CxImage* image = new CxImage();
image->Decode(&memfile,type);
A.把Image編碼存放到內存緩衝中(encode an image in memory)
long size=0;//得到圖像大小
BYTE* buffer=0;//存儲圖像數據的緩衝
image.Encode(buffer,size,image_type);//把image對象中的圖像以type類型數據copy到buffer
free(buffer);
或:
CxMemFile memfile; // 顯式使用CxMemFile對象
memfile.Open();
image.Encode(&memfile,image_type);
BYTE* buffer = memfile.GetBuffer();
long size = memfile.Size();
free(buffer);
4.處理系統粘貼板中的圖像(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();
5.在picture box中顯示一個png格式的文件
HBITMAP m_bitmap = NULL;
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);
其它
一個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;