使用FreeImage写通用图像加载器

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

展开阅读全文

没有更多推荐了,返回首页