|
前言 四大图像库:OpenCV: 功能十分的强大,而且支持目前先进的图像处理技术,体系十分完善,操作手册很详细,手册首先给大家补计算机视觉的知识,几乎涵盖了近10年内的主流算法;
http://sourceforge.net/projects/opencvlibrary/
FreeImage :非常好用的开源图像库,支持二十多种类型的图像和多种图像处理功能。只需一个头文件、一个静态库、一个动态链接库即可。目前还不支持矢量图。C语言的体系,大量使用指针运算速度可以保证,内含先进的多种插值算法。
http://freeimage.sourceforge.net/
CImg :就一个.h文件所以用起来很简明,但感觉功能上不如CxImage。
可以与CxImage配合使用,因为CImg提供了基于lapack的矩阵运算函数和完善的线性滤波卷积函数,同时CImg做像素运算还是很方便的。
http://cimg.sourceforge.net/
CxImage:有一个界面很强的demo程序,
http://www.xdp.it/cximage.htm
FreeImage使用方法
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运行程序。

点击 【文件】->【打开】打开一张图片。。。。。。。


参考资料:源代码:http://freeimage.sourceforge.net/
FreeImage 3.8.0 中文文档
http://cdnetworks-kr-2.dl.sourceforge.net/project/freeimage/Source%20Documentation/3.8.0/FreeImage380Chinese.pdf
Internet ...
|
|