GIF转为IplImage的解决方法

近期要用OpenCV处理GIF图,而该库本身并不支持GIF图,于是想到用转换工具将GIF转换为IplImage格式。

方法一:借助了CxImage能够载入GIF图的优势,由于刚接触CxImage,对其库用法相当生疏,而时间有比较紧,最初的想法很简单,这里采用了一种“欺骗”的手段:

(1)载入GIF图并将其转换为BMP(中间格式);

(2)调用Windows系统命令将中间格式BMP文件隐藏起来;

(3)用OpenCV中的cvImageLoad重新载入BMP文件存为IplImage格式;

(4)再次调用系统命令,将中间文件BMP图像删除。

    #include "cv.h"      //OpenCV should be installed    
    #include "ximage.h"  //CxImage should be installed  
    #define MAXSTRINGSIZE 255  
      
    IplImage*  gif2ipl(const char* filename)  
    {  
        CxImage cxImg;  
        cxImg.Load(filename,CXIMAGE_FORMAT_GIF);  
        cxImg.Save("tmp.bmp",CXIMAGE_FORMAT_BMP);  
        //use the system command to hide the BMP file once it creates;    
        char* strHiden = new char[MAXSTRINGSIZE];  
        sprintf(strHiden,"attrib +h %s","tmp.bmp");  
        system(strHiden);  
        delete[] strHiden;  
        IplImage* img = cvLoadImage("tmp.bmp",CV_LOAD_IMAGE_UNCHANGED);  
      
        //use the system command to delete the BMP temperory file  
        char* strTemp = new char[MAXSTRINGSIZE];  
        sprintf(strTemp,"del /a h %s","tmp.bmp");  
        system(strTemp);//*/  
        delete[] strTemp;  
        return img;  
      
    }  


此种方法有一个问题就是,使用gif2ipl函数时屏幕中会闪现MS-DOS黑屏界面,容易露馅。

方法二:使用FreeImage库,此库较低层,所写的函数都是对数据进行操作,且使用方便,由于GIF图基本上都是具有颜色索引表的

 256色图,颜色深度一般为8位。而IplImage在载入这样的图像时,一般会自动转化为BGR三通道图像,按照这个思路。有下面的代码产生:

    #include <cv.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);  
      
    //  FIBITMAPINFO fiBmpInfo = getfiBmpInfo(fiBmp);  
      
        int width = FreeImage_GetWidth(fiBmp);;  
        int height = FreeImage_GetHeight(fiBmp);  
        //  int depth = fiBmpInfo.depth;  
        //  int widthStep = (width*depth+31)/32*4;  
        //  size_t imgDataSize = widthStep*height*3;  
      
        RGBQUAD* ptrPalette = FreeImage_GetPalette(fiBmp);  
      
        BYTE intens;  
        BYTE* pIntensity = &intens;  
      
        IplImage* iplImg = cvCreateImage(cvSize(width,height),IPL_DEPTH_8U,3);  
      
        iplImg->origin = 1;//should set to 1-top-left structure(Windows bitmap style)  
      
        for (int i=0;i<height;i++)  
        {  
            char* ptrImgDataPerLine = iplImg->imageData + i*iplImg->widthStep;  
      
            for(int j=0;j<width;j++)  
            {  
                            //get the pixel index   
                FreeImage_GetPixelIndex(fiBmp,j,i,pIntensity);    
      
                ptrImgDataPerLine[3*j] = ptrPalette[intens].rgbBlue;  
                ptrImgDataPerLine[3*j+1] = ptrPalette[intens].rgbGreen;  
                ptrImgDataPerLine[3*j+2] = ptrPalette[intens].rgbRed;  
            }  
        }  
      
        FreeImage_Unload(fiBmp);  
        FreeImage_DeInitialise();                 
      
        return iplImg;  
    }  
这样由于使用了cvCreateImage故每次用gif2ipl创建后,程序退出前须使用cvReleaseImage回收内存。

测试程序:

    #include <highgui.h>  
    #include <cv.h>  
    #include "FreeImage.h"  
      
    int main(int argc,char* argv[])  
    {  
      
        char* filename = (argc == 2)? argv[1] :(char*)"workspace.gif";  
      
        IplImage* iplImg = gif2ipl(filename);  
        cvNamedWindow(filename,1);  
        cvShowImage(filename,iplImg);  
        cvWaitKey(0);  
        cvReleaseImage(&iplImg);//if used gif2ipl function ,we must use cvReleaseImage to avoid memory leak;  
        return 0;  
    }  

原文地址:http://blog.youkuaiyun.com/summersolstice/article/details/5123813

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值