C++实现bmp格式图像读写

 更新时间:2021年10月25日 11:22:09   作者:SSS的博客  
这篇文章主要为大家详细介绍了C++实现bmp格式图像读写,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

bmp格式图像有一个特点就是这类数据被分为四个部分:

1.位图文件头(Bitmap File Header) ,大小:14字节

主要包括位图文件大小和位图文件类型信息

2.位图信息头(Bitmap Info Header),大小:40字节

主要包括:位图的宽度和高度,像素为单位、每个像素所占位数(1黑白图像),(4-16色图)、(8-256色图)、(24-真彩色图),新的BMP格式可以支持32位色。 还有其它水平和垂直分辨力(单位:像素/米)等  

3.颜色表(Color Map),大小:4个字节

三大类:蓝色分量、绿色分量、红色分量

4.位图数据(Data Body)

对于2色位图用1位就可以表示该像素,那么1个字节就可以储存8个像素的颜色值

对于16色位图,用4个字节表示一个像素颜色,那么一个字节可以储存2个像素颜色值

对于256色位图,1个字节刚好储存1个像素的颜色值

对于真彩色位图,则需要3个字节才能表示一个像素的颜色值

1.读bmp图像

bool readBmp(char *bmpName)
{
 //二进制读方式打开指定的图像文件
    FILE *fp=fopen(bmpName,"rb");
 if(fp==0) return 0;
 
 
 //跳过位图文件头结构BITMAPFILEHEADER
 fseek(fp, sizeof(BITMAPFILEHEADER),0);
 
 
 //定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中
 BITMAPINFOHEADER head;  
 fread(&head, sizeof(BITMAPINFOHEADER), 1,fp); 
 
 //获取图像宽、高、每像素所占位数等信息
 bmpWidth = head.biWidth;
 bmpHeight = head.biHeight;
 biBitCount = head.biBitCount;
 
 //定义变量,计算图像每行像素所占的字节数(必须是4的倍数)
 int lineByte=(bmpWidth * biBitCount/8+3)/4*4;
 
 //灰度图像有颜色表,且颜色表表项为256
 if(biBitCount==8){
  //申请颜色表所需要的空间,读颜色表进内存
  pColorTable=new RGBQUAD[256];
  fread(pColorTable,sizeof(RGBQUAD),256,fp);
 }
 
 //申请位图数据所需要的空间,读位图数据进内存
 pBmpBuf=new unsigned char[lineByte * bmpHeight];
 fread(pBmpBuf,1,lineByte * bmpHeight,fp);
 
 //关闭文件
 fclose(fp);
 
 return 1;
}

2.写bmp图像

bool saveBmp(char *bmpName, unsigned char *imgBuf, int width, int height, 
    int biBitCount, RGBQUAD *pColorTable)
{
 //如果位图数据指针为0,则没有数据传入,函数返回
 if(!imgBuf)
  return 0;
 
 //颜色表大小,以字节为单位,灰度图像颜色表为1024字节,彩色图像颜色表大小为0
 int colorTablesize=0;
 if(biBitCount==8)
  colorTablesize=1024;
 
 //待存储图像数据每行字节数为4的倍数
 int lineByte=(width * biBitCount/8+3)/4*4;
 
 //以二进制写的方式打开文件
 FILE *fp=fopen(bmpName,"wb");
 if(fp==0) return 0;
 
 //申请位图文件头结构变量,填写文件头信息
 BITMAPFILEHEADER fileHead;
 fileHead.bfType = 0x4D42;//bmp类型
 
 //bfSize是图像文件4个组成部分之和
 fileHead.bfSize= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
  + colorTablesize + lineByte*height;
 fileHead.bfReserved1 = 0;
 fileHead.bfReserved2 = 0;
 
 //bfOffBits是图像文件前三个部分所需空间之和
 fileHead.bfOffBits=54+colorTablesize;
 
 //写文件头进文件
 fwrite(&fileHead, sizeof(BITMAPFILEHEADER),1, fp);
 
 //申请位图信息头结构变量,填写信息头信息
 BITMAPINFOHEADER head; 
 head.biBitCount=biBitCount;
 head.biClrImportant=0;
 head.biClrUsed=0;
 head.biCompression=0;
 head.biHeight=height;
 head.biPlanes=1;
 head.biSize=40;
 head.biSizeImage=lineByte*height;
 head.biWidth=width;
 head.biXPelsPerMeter=0;
 head.biYPelsPerMeter=0;
 //写位图信息头进内存
 fwrite(&head, sizeof(BITMAPINFOHEADER),1, fp);
 
 //如果灰度图像,有颜色表,写入文件 
 if(biBitCount==8)
  fwrite(pColorTable, sizeof(RGBQUAD),256, fp);
 
 //写位图数据进文件
 fwrite(imgBuf, height*lineByte, 1, fp);
 
 //关闭文件
 fclose(fp);
 
 return 1;
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • c语言左移和右移的示例详解

    c语言左移和右移的示例详解

    这篇文章主要介绍了c语言左移和右移的示例详解,移位操作符的两个操作数必须是整型的。整个移位表达式的值的类型也是整型的,而且,左移位操作符与右移位操作符的运算并不对称。
    2020-07-07
  • C++ 中 vector 的常用操作方法汇总

    C++ 中 vector 的常用操作方法汇总

    在C++的STL中,vector是一个动态数组,可以在运行时调整大小,本文介绍了vector的初始化、元素访问、修改、迭代器操作、容量管理以及性能优化技巧,通过这些操作,可以有效地使用vector管理数据,本文介绍C++  vector 操作,感兴趣的朋友一起看看吧
    2024-10-10
  • c语言中比较特殊的输入函数举例详解

    c语言中比较特殊的输入函数举例详解

    C语言提供了丰富的标准库函数,用于处理各种输入输出操作,下面这篇文章主要介绍了c语言中比较特殊的输入函数的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-09-09
  • Qt物联网管理平台之实现自动清理早期数据功能

    Qt物联网管理平台之实现自动清理早期数据功能

    随着时间的增加,存储的历史记录也在不断增加,如果设备数量很多,存储间隔很短,不用多久,数据库中的记录就非常多,至少是百万级别起步,而且有些用户还是需要存储每一次的采集的数据。本文将利用Qt实现自动清理早期数据,需要的可以参考一下
    2022-07-07
  • C++解决输出链表中倒数k个结点的问题

    C++解决输出链表中倒数k个结点的问题

    这篇文章主要给大家介绍了关于如何利用C++解决输出链表中倒数k个结点的问题,文中通过实例代码介绍的非常详细,对大家学习或者使用C++具有一定的参考学习价值,需要的朋友可以参考下
    2021-12-12
  • memset函数的使用分析

    memset函数的使用分析

    本篇文章是对memset函数的使用进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C/C++中宏/Macro的深入讲解

    C/C++中宏/Macro的深入讲解

    这篇文章主要给大家介绍了关于C/C++中宏/Macro的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用C/C++具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-06-06
  • C语言中getchar( ) 函数使用详解

    C语言中getchar( ) 函数使用详解

    getchar() 字符输入函数,没有参数,从输入缓冲区里面读取一个字,需要注意一次只能读取一个字符,这篇文章主要介绍了C语言中getchar函数使用详解,需要的朋友可以参考下
    2022-12-12
  • C++ Leetcode实现从英文中重建数字

    C++ Leetcode实现从英文中重建数字

    本文主要介绍了当给你一个字符串s,其中包含字母顺序打乱的用英文单词表示的若干数字(0-9)时,如何通过Leetcode按升序返回原始的数字。感兴趣的童鞋可以来看看
    2021-11-11
  • C语言实现快速排序算法实例

    C语言实现快速排序算法实例

    快速排序时间复杂度为O(nlogn),是数组相关的题目当中经常会用到的算法,下面这篇文章主要给大家介绍了关于C语言实现快速排序算法的相关资料,需要的朋友可以参考下
    2022-06-06

最新评论