c语言解析bmp图片的实例

 更新时间:2017年08月05日 08:19:05   投稿:jingxian  
下面小编就为大家带来一篇c语言解析bmp图片的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

心血来潮想了解下常用图片的格式解析,翻看了一些资料后,发现最简单的是bmp格式,所以先拿它开刀。

BMP格式

这种格式内的数据分为三到四个部分,依次是:

文件信息头 (14字节)存储着文件类型,文件大小等信息

图片信息头 (40字节)存储着图像的尺寸,颜色索引,位平面数等信息

调色板 (由颜色索引数决定)【可以没有此信息】

位图数据 (由图像尺寸决定)每一个像素的信息在这里存储

一般的bmp图像都是24位,也就是真彩。每8位为一字节,24位也就是使用三字节来存储每一个像素的信息,三个字节对应存放r,g,b三原色的数据,每个字节的存贮范围都是0-255。

那么以此类推,32位图即每像素存储r,g,b,a(Alpha通道,存储透明度)四种数据。8位图就是只有灰度这一种信息,还有二值图,它只有两种颜色,黑或者白。

文件信息头格式

typedef struct tagBITMAPFILEHEADER {
  unsigned short bfType;   // 19778,必须是BM字符串,对应的十六进制为0x4d42,十进制为19778
  unsigned int bfSize;    // 文件大小
  unsigned short bfReserved1; // 一般为0
  unsigned short bfReserved2; // 一般为0
  unsigned int bfOffBits;   // 从文件头到像素数据的偏移,也就是这两
} BITMAPFILEHEADER;

图片信息头格式

typedef struct tagBITMAPINFOHEADER {
  unsigned int biSize;    // 此结构体的大小
  int biWidth;        // 图像的宽
  int biHeight;        // 图像的高
  unsigned short biPlanes;  // 1
  unsigned short biBitCount; // 一像素所占的位数,一般为24
  unsigned int biCompression; // 0
  unsigned int biSizeImage;  // 像素数据所占大小, 这个值应该等于上面文件头结构中bfSize-bfOffBits
  int biXPelsPerMeter;    // 0
  int biYPelsPerMeter;    // 0
  unsigned int biClrUsed;   // 0 
  unsigned int biClrImportant;// 0
} BITMAPINFOHEADER;

调色板信息

这里需要根据文件信息头的bfOffBits是否等于54(由前面的固定14+40字节得出)来判断是否存在此调色板信息,如果是,则不存在;大于的话即存在。

可以根据需求提取其中的信息,或者直接移动到位图数据区读取像素信息。

这个地方可以表示为一个二维数组unsigned char palette[N][M], 其中N表示总的颜色索引数,M表示每像素占的字节数。例如一个24位图,每像素由3个字节构成,M即为3,每个字节可表示0-255共256种颜色,所以N为256 。

数组中存放的是索引信息,也就是一张映射表,标识颜色索引号与其代表的颜色的对应关系

位图数据

这里就存放着所有的像素信息了,每像素为一字节,读取出来后通过查询调色板获得颜色信息。

如果图像是24位或是32位数据的位图的话,位图数据区就不是索引而是实际的像素值了。下面说明一下,此时位图数据区的每个像素的RGB颜色阵列排布:

24位RGB按照BGR的顺序来存储每个像素的各颜色通道的值,一个像素的所有颜色分量值都存完后才存下一个下一个像素,不进行交织存储。

32位数据按照BGRA的顺序存储,其余与24位位图的方式一样。

注意:由于位图信息头中的图像高度是正数,所以位图数据在文件中的排列顺序是从左下角到右上角,以行为主序排列的。

也就是说,最先读取到的是位于从上往下数最后一行最左端的像素,然后是同行向右一列的像素,读取完一整行后,继续读取倒数第二行,然后继续向上直到读完所有数据。

以上这篇c语言解析bmp图片的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • C++任意线程通过hwnd实现将操作发送到UI线程执行

    C++任意线程通过hwnd实现将操作发送到UI线程执行

    做Windows界面开发时,经常需要在多线程环境中将操作抛到主线程执行,下面我们就来学习一下如何在不需要重新定义消息以及接收消息的情况下实现这一要求,感兴趣的可以了解下
    2024-03-03
  • C读txt到二维数组的实现方法

    C读txt到二维数组的实现方法

    下面小编就为大家带来一篇C读txt到二维数组的实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-12-12
  • Visual Studio Code运行C++代码时显示CLOCKS_PER_SEC未定义的问题及解决方法

    Visual Studio Code运行C++代码时显示CLOCKS_PER_SEC未定义的问题及解决方法

    这篇文章主要介绍了解决Visual Studio Code运行C++代码时显示CLOCKS_PER_SEC未定义的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-04-04
  • 如何在C语言中判断socket是否已经断开

    如何在C语言中判断socket是否已经断开

    如果不主动关闭socket的话,系统不会自动关闭的,除非当前进程挂掉了,操作系统把占用的socket回收了才会关闭。小编今天跟大家简单介绍下如何在C语言中判断socket是否已经断开
    2019-05-05
  • C语言模拟实现动态通讯录

    C语言模拟实现动态通讯录

    本文主要介绍了C语言模拟实现动态通讯录,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • 深入C++四种强制类型转换的总结

    深入C++四种强制类型转换的总结

    本篇文章是对C++中四种强制类型转换进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C语言实现扫雷小游戏(适合初学者)

    C语言实现扫雷小游戏(适合初学者)

    这篇文章主要为大家详细介绍了C语言实现扫雷小游戏,适合初学者练习,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • 贪心算法的C语言实现与运用详解

    贪心算法的C语言实现与运用详解

    这篇文章主要介绍了贪心算法的C语言实现与运用详解,运用么,就是文中所附的ACM练习题,哈哈:D需要的朋友可以参考下
    2015-08-08
  • C语言中条件判断的正确使用姿势

    C语言中条件判断的正确使用姿势

    在C语言中,有三种条件判断结构:if语句、if-else语句和switch语句,这篇文章主要来和大家讲解一下它们的正确使用姿势,需要的可以参考一下
    2023-05-05
  • C++中replace()函数使用方法汇总

    C++中replace()函数使用方法汇总

    这篇文章主要介绍了C++中replace()函数使用方法汇总,在这篇文章中为大家详细介绍C++ replace()函数的各种应用方式,希望朋友们可以从这里介绍的内容充分掌握这一应用技巧
    2015-11-11

最新评论