FreeImage的使用及 opencv读取gif

因为要用opencv对gif进行处理,查了下,发现有个 FreeImage 的库 可以用。

FreeImage官网: http://freeimage.sourceforge.net/

下载后,拷贝出 FreeImage.dll FreeImage.lib, FreeImage.h 这是有用的文件。很奇怪这个项目居然没有文档说明,只有一些exmaple。

直接贴代码吧,节省时间。这个例程是可以直接读取gif的每一帧然后显示的。

//gif2ipl.cpp
#include <cv.h> 
#include <highgui.h> 
#include "FreeImage.h" 
IplImage*  gif2ipl(const char* filename) 

    FreeImage_Initialise();         //load the FreeImage function lib 
    FREE_IMAGE_FORMAT fif = FIF_GIF; 
    FIBITMAP* fiBmp = FreeImage_Load(fif,filename,GIF_DEFAULT); 
    FIMULTIBITMAP * pGIF=FreeImage_OpenMultiBitmap(fif,filename,0,1,0,GIF_PLAYBACK);
    //  FIBITMAPINFO fiBmpInfo = getfiBmpInfo(fiBmp); 
    int gifImgCnt=FreeImage_GetPageCount(pGIF);
    FIBITMAP * pFrame;
    int width,height;
    width=FreeImage_GetWidth(fiBmp);
    height=FreeImage_GetHeight(fiBmp);
    IplImage * iplImg = cvCreateImage(cvSize(width,height),IPL_DEPTH_8U,3); 
        iplImg->origin = 1;//should set to 1-top-left structure(Windows bitmap style) 
    RGBQUAD* ptrPalette =new RGBQUAD; // = FreeImage_GetPalette(fiBmp); 
    BYTE intens; 
    BYTE* pIntensity = &intens; 
    cvNamedWindow("gif",0);
    printf("gifImgCnt %d \n",gifImgCnt);
    for (int curFrame=0;curFrame<gifImgCnt;curFrame++)
    {
        pFrame= FreeImage_LockPage(pGIF,curFrame);
        //ptrPalette = FreeImage_GetPalette(pFrame); 
        char * ptrImgDataPerLine;
        for (int i=0;i<height;i++) 
        { 
            ptrImgDataPerLine = iplImg->imageData + i*iplImg->widthStep; 
            for(int j=0;j<width;j++) 
            { 
                //get the pixel index  
                //FreeImage_GetPixelIndex(pFrame,j,i,pIntensity);   
                FreeImage_GetPixelColor(pFrame,j,i,ptrPalette);
                ptrImgDataPerLine[3*j] = ptrPalette->rgbBlue; 
                ptrImgDataPerLine[3*j+1] = ptrPalette->rgbGreen; 
                ptrImgDataPerLine[3*j+2] = ptrPalette->rgbRed; 
                //ptrImgDataPerLine[3*j] = ptrPalette[intens].rgbBlue; 
                //ptrImgDataPerLine[3*j+1] = ptrPalette[intens].rgbGreen; 
                //ptrImgDataPerLine[3*j+2] = ptrPalette[intens].rgbRed; 
            } 
        }
        
        printf("convert curFrame end %d \n",curFrame);
        cvShowImage("gif",iplImg);
        cvWaitKey(30);
        FreeImage_UnlockPage(pGIF,pFrame,1);
    }
    FreeImage_Unload(fiBmp); 
    FreeImage_DeInitialise();    
    return iplImg;

main.cpp:

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <highgui.h> 
#include <cv.h> 
#include "opencv2/opencv.hpp"
#include "FreeImage.h" 
 
IplImage*  gif2ipl(const char* filename);
int main(int argc,char* argv[]) 

 
    char* filename = (argc == 2)? argv[1] :(char*)"worldCup.gif"; 
 
    IplImage* iplImg = gif2ipl(filename);  
    cvReleaseImage(&iplImg);//if used gif2ipl function ,we must use cvReleaseImage to avoid memory leak; 
    return 0; 

我用 mingw编译:makefile:

opencvInclude= -I C:\opencv2.4.4\build\include -I C:\opencv2.4.4\build\include\opencv -I C:\opencv2.4.4\build\include\opencv2
freeimageInclude= -I ../FreeImageLib
cppFlags=-Wall -O2
#cppFlags=-Wall -g

target:main.o gif2ipl.o
    g++ $(cppFlags) -o target main.o gif2ipl.o -L E:\Learn\OpenCV\opencv2.4.4\opencv2.4\build\x86\mingw\lib -lopencv_core244 -lopencv_imgproc244 -lopencv_highgui244  -L../FreeImageLib -lFreeImage

main.o:main.cpp
    g++ $(cppFlags) $(opencvInclude) $(freeimageInclude) -o main.o -c main.cpp

gif2ipl.o:gif2ipl.cpp
    g++ $(cppFlags) $(opencvInclude) $(freeimageInclude) -o gif2ipl.o -c gif2ipl.cpp

.PHONY:clean
clean:
    -del *.o target

实际这个转换感觉要操作每一个像素比较费时间,能否直接让 IplImage 的 imageData 指向 FreeImage 读取数据的那片内存了? 对于单通道图片,我测试时可以的,但是 gif 似乎最高只支持8位256色,所以如果 IplImage是 8位3通道,就不行了,因为数据的内存布局不同。

posted @ 2013-09-15 21:44  tofixer  阅读(7529)  评论(0编辑  收藏  举报