原文:http://www.cnblogs.com/monkeyhey/p/3927857.html

网上有将gif转为iplimg的版本,只是用惯了C++的接口,所以就写了个转Mat的版本,代码比较简单

一、读文件

 1     int MatFun::gif2Mat(char* data, size_t dataSize, vector<Mat>& gifImgs, Mat& singleImg)
 2     {
 3         /* initialise
 4         ->open memory
 5         ->getImageType
 6         ->load bitmaps
 7         ->bitmaps to Mat
 8         ->free all resource
 9         */
10         // condition1: data is not null
11         if (NULL == data || dataSize == 0)
12             return -1;
13         FreeImage_Initialise();
14         FIMEMORY* memory = FreeImage_OpenMemory((BYTE*)data, dataSize);
15         if (NULL==memory)
16         {
17             FreeImage_DeInitialise();   //condition 2: memory is not null
18         }
19
20         FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromMemory(memory);
21         if (FIF_UNKNOWN == fif)    //condition 3: type of image should be know
22         {
23             fprintf(stderr, "unknown type of image");
24             if (NULL != memory) FreeImage_CloseMemory(memory);
25             FreeImage_DeInitialise();
26             return -1;
27         }
28         else if (FIF_GIF != fif)  //condition 4: type of image should be GIF
29         {
30             if (NULL != memory) FreeImage_CloseMemory(memory);
31             FreeImage_DeInitialise();
32             return 0;
33         }
34
35         FIMULTIBITMAP * fiBmp = FreeImage_LoadMultiBitmapFromMemory(fif, memory, GIF_DEFAULT);
36         if (NULL==fiBmp)
37         {
38             if (NULL != memory) FreeImage_CloseMemory(memory);   //condition 5: bitmaps is not null
39             FreeImage_DeInitialise();
40             return -1;
41         }
42
43         int num = FreeImage_GetPageCount(fiBmp);
44
45         for (int i = 0; i < num; i++)
46         {
47             if (i==0 || i==2)
48             {
49                 FIBITMAP *mfibmp = FreeImage_LockPage(fiBmp, i);
50                 if (mfibmp)
51                 {
52                     Mat dst = bitMap2Mat(mfibmp, fif);
53                     FreeImage_UnlockPage(fiBmp, mfibmp, false);
54                     if (dst.empty())
55                     {
56                         if (NULL != memory) FreeImage_CloseMemory(memory);
57                         if (NULL != fiBmp) FreeImage_CloseMultiBitmap(fiBmp, GIF_DEFAULT);
58                         FreeImage_DeInitialise();
59                         return -1;
60                     }
61                     gifImgs.push_back(dst);
62                     dst.release();
63                 }
64             }
65         }
66
67         if (NULL != memory)
68             FreeImage_CloseMemory(memory);
69         if (NULL != fiBmp)
70             FreeImage_CloseMultiBitmap(fiBmp);
71         FreeImage_DeInitialise();
72
73         return 0;
74     }

这部分其实功能很简单,代码里面大部分都是检查,实际执行就初始化、打开内存、内存中读bitmap这几步。

二、gif转Mat

    Mat MatFun::bitMap2Mat(FIBITMAP* fiBmp, const FREE_IMAGE_FORMAT &fif){if (NULL == fiBmp || FIF_GIF != fif)return Mat();int width = FreeImage_GetWidth(fiBmp);int height = FreeImage_GetHeight(fiBmp);BYTE intensity;BYTE* pIntensity = &intensity;if(FreeImage_GetBPP(fiBmp) !=8)fiBmp = FreeImage_ConvertTo8Bits(fiBmp); //必须转化为8bitRGBQUAD* pixels = new RGBQUAD; pixels = FreeImage_GetPalette(fiBmp);Mat img=Mat::zeros(height, width, CV_8UC3);uchar* p;for (int i = 0; i < height; i++){p = img.ptr<uchar>(i);for (int j = 0; j < width; j++){FreeImage_GetPixelIndex(fiBmp, j, i, pIntensity);p[3 * j] = pixels[intensity].rgbBlue;p[3 * j + 1] = pixels[intensity].rgbGreen;p[3 * j + 2] = pixels[intensity].rgbRed;}}return img;}

具体的将byte像素转化为mat里面的像素值即可,注意rgb图像的Mat里是一个像素包含三通道的值,知道这点,代码就很好理解了。

#include <FreeImage.h>
#include <opencv2\opencv.hpp>
using namespace cv;void FI2MAT(FIBITMAP* src, Mat& dst)
{//FIT_BITMAP    //standard image : 1 - , 4 - , 8 - , 16 - , 24 - , 32 - bit//FIT_UINT16    //array of unsigned short : unsigned 16 - bit//FIT_INT16     //array of short : signed 16 - bit//FIT_UINT32    //array of unsigned long : unsigned 32 - bit//FIT_INT32     //array of long : signed 32 - bit//FIT_FLOAT     //array of float : 32 - bit IEEE floating point//FIT_DOUBLE    //array of double : 64 - bit IEEE floating point//FIT_COMPLEX   //array of FICOMPLEX : 2 x 64 - bit IEEE floating point//FIT_RGB16     //48 - bit RGB image : 3 x 16 - bit//FIT_RGBA16    //64 - bit RGBA image : 4 x 16 - bit//FIT_RGBF      //96 - bit RGB float image : 3 x 32 - bit IEEE floating point//FIT_RGBAF     //128 - bit RGBA float image : 4 x 32 - bit IEEE floating pointint bpp = FreeImage_GetBPP(src);FREE_IMAGE_TYPE fit = FreeImage_GetImageType(src);int cv_type = -1;int cv_cvt = -1;switch (fit){case FIT_UINT16: cv_type = DataType<ushort>::type; break;case FIT_INT16: cv_type = DataType<short>::type; break;case FIT_UINT32: cv_type = DataType<unsigned>::type; break;case FIT_INT32: cv_type = DataType<int>::type; break;case FIT_FLOAT: cv_type = DataType<float>::type; break;case FIT_DOUBLE: cv_type = DataType<double>::type; break;case FIT_COMPLEX: cv_type = DataType<Complex<double>>::type; break;case FIT_RGB16: cv_type = DataType<Vec<ushort, 3>>::type; cv_cvt = COLOR_RGB2BGR; break;case FIT_RGBA16: cv_type = DataType<Vec<ushort, 4>>::type; cv_cvt = COLOR_RGBA2BGRA; break;case FIT_RGBF: cv_type = DataType<Vec<float, 3>>::type; cv_cvt = COLOR_RGB2BGR; break;case FIT_RGBAF: cv_type = DataType<Vec<float, 4>>::type; cv_cvt = COLOR_RGBA2BGRA; break;case FIT_BITMAP:switch (bpp) {case 8: cv_type = DataType<Vec<uchar, 1>>::type; break;case 16: cv_type = DataType<Vec<uchar, 2>>::type; break;case 24: cv_type = DataType<Vec<uchar, 3>>::type; break;case 32: cv_type = DataType<Vec<uchar, 4>>::type; break;default:// 1, 4 // Unsupported nativelycv_type = -1;}break;default:// FIT_UNKNOWN // unknown typedst = Mat(); // return empty Matreturn;}int width = FreeImage_GetWidth(src);int height = FreeImage_GetHeight(src);int step = FreeImage_GetPitch(src);if (cv_type >= 0) {dst = Mat(height, width, cv_type, FreeImage_GetBits(src), step);if (cv_cvt > 0){cvtColor(dst, dst, cv_cvt);}}else {vector<uchar> lut;int n = pow(2, bpp);for (int i = 0; i < n; ++i){lut.push_back(static_cast<uchar>((255 / (n - 1))*i));}FIBITMAP* palletized = FreeImage_ConvertTo8Bits(src);BYTE* data = FreeImage_GetBits(src);for (int r = 0; r < height; ++r) {for (int c = 0; c < width; ++c) {dst.at<uchar>(r, c) = saturate_cast<uchar>(lut[data[r*step + c]]);}}}flip(dst, dst, 0);
}int main()
{FreeImage_Initialise();FREE_IMAGE_FORMAT format = FreeImage_GetFileType("path_to_image", 0);FIBITMAP* fi_image = FreeImage_Load(format, "path_to_image");Mat cv_img;FI2MAT(fi_image, cv_img);return 0;
}

利用FreeImage将gif图像转为opencv中的Mat相关推荐

  1. C语言使用指针处理opencv中的Mat图像数据

    1.在处理图像时,一般直接使用opencv中的imread函数获取图片,但是获取到图片后没有用到opencv中的其他算法时,直接用图片处理就会出现耗时严重的情况,所以需要将图片形式转换成指针数组形式处 ...

  2. 遍历opencv中的mat像素的几种方法和概念

    今天在看矩形滤波的时候忽然脑子短路,把一些概念全弄混了,现总结一下,以便下次再混的时候可以参考确认下,自己的理解,有错的地方还请指正. 首先,在Opencv2中基本上都是用的Mat来表示图像了,C++ ...

  3. opencv中的Mat图使用CDC显示

    需求:MFC显示opencv读取的Mat图 代码: 1.中间转化的函数: //************************************ // 函数名称: Show2DC // 访问权限 ...

  4. 如何将OpenCV中的Mat类绑定为OpenGL中的纹理

    https://blog.csdn.net/TTTTzTTTT/article/details/53456324 如果要调用外接的USB摄像头获取图像通常使用OpenCV来调用,如何调用摄像头请参考本 ...

  5. c++版opencv中的Mat数据类型的说明

    一直使用mat,很好用,但是细扣又说不清楚到底是怎样的一种数据类型,今天学习下. 一.先上硬货结论: 浅拷贝:拷贝构造函数和赋值运算符只复制信息头,即实际上还是同个图像数据.mat中存储同个数据地址: ...

  6. opencv中的Mat类型

    Mat类型主要是跟matlab中的数据类型一样.故用起来很方便. Mat最大的优势跟STL很相似,都是对内存进行动态的管理,不需要之前用户手动的管理内存,对于一些大型的开发,有时候投入的lpImage ...

  7. opencv中查看mat位图的像素幅度(Cv::matStep)

    实例 其中step里的 ,其中数据指针首地址是p=0x000000000028d7b0,1280是每行数据所占的字节数,1是每个元素的字节数. Mat的作用 The class Mat represe ...

  8. QImage与OpenCV中的MAT图像格式转换

    1.Mat转换为QImage QImage Mat2QImage(const Mat& mat) { Mat rgb; cvtColor(mat, rgb, CV_BGR2RGB);     ...

  9. 在OpenCV中利用卷积进行图像滤波

    简 介: 本文首先讨论了卷积核的概念,以及如何用于对图像进行滤波.然后通过他们对图像进行数学运算来实现特定的效果,比如平和和锐化.展示了如何在OpenCV中实现2D滤波. 在等同卷积卷积核之后,我们创 ...

最新文章

  1. LeetCode 11. Container With Most Water--Java 解法--困雨水简单版
  2. c++ 读文件 文件指针 继续读_FatFs文件系统使用笔记
  3. 这老哥把GPU当暖气用,省钱了
  4. Git知识点笔记-基本常识
  5. 用矩阵内积的办法构造迭代次数受控的神经网络1:0.6:0.1=4:3:2
  6. Arduino--蓝牙
  7. vSAN ReadyNode™中可以(也不能)更改的内容
  8. 基于Spring Security的认证方式_Spring Security 的认证流程_Spring Security OAuth2.0认证授权---springcloud工作笔记123
  9. swagger在springboot上的快速上手
  10. BTC 重现“自由落体”式暴跌,原来是受这几个因素影响?
  11. Selenium爬虫 -- 图片视频的src绝对地址链接分析
  12. Atitit 判断判断一张图片是否包含另一张小图片
  13. 算法:回溯二 生成有效括号对Generate Parentheses
  14. SVN安装以及使用教程
  15. python写出租车计费系统_基于VHDL的出租车计费器
  16. Eureka Client 源码解析
  17. java实现excel转pdf_java实现excel转pdf(poi+itext)
  18. 深入理解哈希表(JAVA和Redis哈希表实现)
  19. 微信小程序实现多页面
  20. 渐变(Gradients)

热门文章

  1. 三次样条插值三弯矩matlab_三次样条(cubic spline)插值
  2. 2003服务器系统屏蔽广告,电脑总是乱弹广告弹窗?教你彻底关闭
  3. python中进制_python中进制的算法
  4. vba mysql odbc_使用VBA+ODBC+MySQL实现Excel网络版
  5. springmvc 配置 fastjson解析器
  6. 我的世界服务器修改飞行速度,《我的世界》创造模式飞行速度修改方法介绍
  7. 知乎热议:计算机专业钱景究竟如何?
  8. 知乎高赞:iOS 为什么感觉比 Android 流畅?
  9. SpringBoot + Mybatis + Druid + PageHelper 实现多数据源分页
  10. 面试:为什么 https 比 http 更安全?