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; }

 

你可能感兴趣的:(windows,function,command,delete,System,structure)