使用FreeImage写通用图像加载器

来源:互联网 发布:最好的大六壬排盘软件 编辑:程序博客网 时间:2024/06/06 02:55

FreeImage库支持多种类型图像的特性让我有一种想法,写一个通用图像加载显示器,由于又刚好在学习MFC,于是也就抱着写着玩的心态开始了,FreeImage可以很轻松的加载各种格式的图像,但是显示这些图像又让我犯难了。MFC庞大的框架确实很头疼,但是一旦你明确目标是什么,框架也就不成其为问题。所有的主体代码都是在视类完成的。

注意:使用FreeImage库前,须将FreeImage动态库FreeImage.dll,FreeImage.lib和头文件FreeImage.h放在工程目录下,并将FreeImage.lib添加到工程中,可在工程中使用#pragma commet(lib,"FreeImage.lib"宏,或直接在Project->Settings->Link选项中添加。比添加头文件FreeImage.h在相应的地方。

第一步:通用图像加载;

通用图像的加载函数:FIBITMAP* GenericLoader(const char *ptrFileName)

    FIBITMAP* CGenericPictureReaderView::GenericLoader(const char *ptrFileName)      {          FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;                    fif = FreeImage_GetFileType(ptrFileName);          if(fif == FIF_UNKNOWN)          {              fif = FreeImage_GetFIFFromFilename(ptrFileName);          }          if(fif != FIF_UNKNOWN && FreeImage_FIFSupportsReading(fif))          {              FIBITMAP* dib = FreeImage_Load(fif,ptrFileName,0);                            return dib;          }          return NULL;      }  


第二步:设置菜单栏的打开操作的消息响应函数;

其代码如下:

    void CGenericPictureReaderView::OnFileOpen()       {          // TODO: Add your command handler code here          // TODO: Add your command handler code here          CFileDialog fileDlg(TRUE,NULL,"*.*",OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,          "all(*.*)|*.*|bmp(*.bmp)|*.bmp|/          jpg(*.jpg)|*.jpg|png(*.png)|*.png|/          tif(*.tif)|*.tif|gif(*.gif)|*.gif|/          psd(*.psd)|*.psd|pgm(*.pgm)|*pgm||",          NULL);                    RECT rt;          GetClientRect(&rt);          if(IDOK == fileDlg.DoModal())          {              strFileName = fileDlg.GetPathName();      //      SetWindowText(strFileName);              AfxGetMainWnd()->SetWindowText(strFileName);              InvalidateRect(&rt);          }      }  


第三步:显示图像

图像分为两种类型,第一种:没有调色板的图像,直接使用StretchDIBit函数绘制。第二种:使用调色板,先载入调色板,然后使用StretchDIBit函数绘制。

有调色板的图像,先要创建调色板,下面就是根据FIBITMAP创建调色板的函数:

    HPALETTE CGenericPictureReaderView::GetPalette(FIBITMAP *dib)      {          struct            {              WORD Version;              WORD NumberOfEntries;              PALETTEENTRY palPalEntry[256];          } palette = {0x300,256};                RGBQUAD* ptrRGBTable = FreeImage_GetPalette(dib);          UINT nClrUsed = FreeImage_GetColorsUsed(dib);          for(UINT i=0;i<nClrUsed;i++)          {              palette.palPalEntry[i].peBlue = ptrRGBTable[i].rgbBlue;              palette.palPalEntry[i].peGreen = ptrRGBTable[i].rgbGreen;              palette.palPalEntry[i].peRed = ptrRGBTable[i].rgbRed;              palette.palPalEntry[i].peFlags = 0;          }                HPALETTE Palette = CreatePalette((LPLOGPALETTE)&palette);                return Palette;      }  

在OnDraw函数中进行绘制操作:

    void CGenericPictureReaderView::OnDraw(CDC* pDC)      {          CGenericPictureReaderDoc* pDoc = GetDocument();          ASSERT_VALID(pDoc);          // TODO: add draw code for native data here          FIBITMAP* dib = GenericLoader(strFileName);                int width = FreeImage_GetWidth(dib);          int height = FreeImage_GetHeight(dib);          BITMAPINFO* pBitmapInfo = FreeImage_GetInfo(dib);          BYTE* pImgData = FreeImage_GetBits(dib);          RGBQUAD* pPalette = FreeImage_GetPalette(dib);          if(pPalette)          {              HPALETTE Pal = GetPalette(dib);                    HPALETTE oldPal = ::SelectPalette(pDC->GetSafeHdc(),Pal,TRUE);                    ::RealizePalette(pDC->GetSafeHdc());              ::StretchDIBits(pDC->GetSafeHdc(),0,0,width,height,0,0,width,height,                  (const void*)pImgData,pBitmapInfo,DIB_RGB_COLORS,SRCCOPY);                        ::SelectPalette(pDC->GetSafeHdc(),oldPal,TRUE);              ::DeleteObject((HGLOBAL)Pal);          }          else          {              ::StretchDIBits(pDC->m_hDC,0,0,width,height,0,0,width,height,              (const void*)pImgData,pBitmapInfo,DIB_RGB_COLORS,SRCCOPY);          }          FreeImage_Unload(dib);      }  

当需要发行你的程序时,需要将动态链接库FreeImage.dll一起打包发行。

使用FreeImage大大减轻了图像载入的工作,如果全得自己写,想想后果吧!那么多图像格式,你不得不自己设计自己的图像类,工作量是极其反复的。据称,FreeImage基本可以支持所有的主流格式,其支持的文件格式有十几种之多。真是个好东西啊!


原文地址:http://blog.csdn.net/summersolstice/article/details/5148258

0 0