FreeImage支持20多种图像类型的(如BMP、JPEG、GIF、PNG、TIFF等)图像处理库。如下图FreeImage允许的位图格式:
FreeImage的使用例子好像很少,这里以Visual Studio 2008+SP1为例说明怎么使用FreeImage图形库。
FreeImage下载是在http://freeimage.sourceforge.net/ ,解压缩后里面有个Dist的文件夹,这里面的五个文件就是我们用FreeImage所需要的全部东东了,即FreeImage.lib、FreeImage.dll、FreeImaged.lib、FreeImaged.dll、FreeImage.h,以d 结尾的库文件用于Debug版本,没有的用于Release版本的。
一、新建一个名称为FITest的MFC单文档应用程序,将FreeImage中的Dist文件夹添加到“工具->选项->项目和解决方案->VC++目录”中的“包含文件”与“库文件”中;
二、初始化
(1)、在stdafx.h 文件中加入如下代码:
#include"FreeImage.h"#ifdef _DEBUG#pragma comment(lib, "FreeImaged.lib")#else#pragma comment(lib, "FreeImage.lib")#endif(2)、例外默认情况下,FreeImage 被当作动态链接库。若需用作静态链接库,则在应用程序类的InitInstance 中调用FreeImage_Initialise(0)来初始化FreeImage库。
(3)、重载ExitInstance 并在其中调用FreeImage_DeInitialise()释放FreeImage 库。这个必须在程序的结尾处唯一地一次调用该函数,以清除FreeImage库在内存中分配的内存,不然会造成很严重的内存泄露。
int CFITestApp::ExitInstance()
{
// TODO: 在此添加专用代码和/或调用基类
FreeImage_DeInitialise();
return CWinAppEx::ExitInstance();
}
三、读取图像
(1)、给CFITestDoc类添加一个public变量
FIBITMAP *m_handleFI;
在类的构造函数添加 :m_handleFI(NULL) 字样,即
CFITestDoc::CFITestDoc():m_handleFI(NULL)
{
// TODO: 在此添加一次性构造代码
}
(2)、给CFITestDoc类添加两个函数,FreeDIB ()和LoadDIB(LPCTSTR lpszPathName, int flag)
函数代码如下
FIBITMAP* CFITestDoc::LoadDIB(LPCTSTR lpszPathName, int flag)
{
FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
fif = FreeImage_GetFileType(lpszPathName); // ansi情况下,LPCTSTR 就是 const char*, 是常量字符串
if(fif == FIF_UNKNOWN)
fif = FreeImage_GetFIFFromFilename(lpszPathName);
if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif))
{
FIBITMAP *dib = FreeImage_Load(fif,lpszPathName, flag);
return dib;
}
return NULL;
}
void CFITestDoc::FreeDIB(void)
{
if(m_handleFI)
{
FreeImage_Unload(m_handleFI);// 释放位图
m_handleFI = NULL;
}
}
(3)、在析构函数中释放位图
CFITestDoc::~CFITestDoc()
{
FreeDIB();
}(4)、为CFITestDoc类添加ID_FILE_OPEN的COMMAND事件响应函数OnFileOpen()
void CFITestDoc::OnFileOpen()
{
FIBITMAP* pFI = NULL;
CString szFilter("BMP file(*.bmp)|*.bmp|GPEG file(*.jpg)|*.jpg|All files(*.*)|*.*||");
CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY, szFilter);
if(dlg.DoModal() == IDOK)
{
CString strPath = dlg.GetPathName();
pFI = LoadDIB(strPath, 0);
if(pFI)
{
FreeDIB();// 释放以前的位图
m_handleFI = pFI;// 指向新位图
UpdateAllViews (NULL);
}
}
}
四、显示图像
在视图类CFITestView中的OnDraw()函数添加代码
void CFITestView::OnDraw(CDC* pDC) //记得去掉注释掉的pDC
{
CFITestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
// TODO: 在此处为本机数据添加绘制代码FIBITMAP *pFI = pDoc->m_handleFI;if(pFI){BYTE* pBits = FreeImage_GetBits(pFI);
BITMAPINFO* pIf=FreeImage_GetInfo(pFI);int W = FreeImage_GetWidth(pFI);
int H = FreeImage_GetHeight(pFI);
CRect rectClient;GetClientRect(rectClient);
int dstW = rectClient.Width();
int dstH = rectClient.Height();
::SetStretchBltMode(pDC->GetSafeHdc(),COLORONCOLOR);
if(dstW == W && dstH == H)
{
::SetDIBitsToDevice(pDC->GetSafeHdc(),0,0, W, H,0,0,0, H,pBits,pIf,DIB_RGB_COLORS);
}
else {// 按比例缩放
float fScale=(float)(W*dstH)/(float)(H*dstW);
if(fScale > 1.0f)
dstH = (int) (dstH / fScale);
else
dstW = (int) (dstW * fScale);
::StretchDIBits(pDC->GetSafeHdc(),0,0,dstW,dstH,0,0,W,H,pBits,pIf,DIB_RGB_COLORS,SRCCOPY);
}
}
}
五、调试程序
调试程序要注意了,可能在LoadDIB函数中出现错误,提示LPCTSTR不能转换成const char * ,本来在ANSI下两者是一样的,设置一下项目属性。
按Alt+F7快捷键,如下图,设置字符集为【使用多字节字符集】
记得把FreeImaged.dll拷贝到...\FITest\Debug下,FreeImage.dll拷贝到...\FITest\Release目录下。或都拷贝到C:\WINDOWS\system32\下也行。
按Ctrl+F5运行程序。
点击 【文件】->【打开】打开一张图片。。。。。。。