BMP文件是Windows操作系统所推荐和支持的图像文件格式,是一种将内存或显示器的图像数据不经过压缩而直接按位存盘的文件格式,所以称为位图(bitmap)文件。

BMP文件结构

BMP图像文件包括四个部分:

1、位图文件头(Bitmap File Header)

2、位图信息头(Bitmap Info Header)

3、颜色表(Color Map)

4、图像数据(即图像数据,Data Bits)

一、位图文件头,是一个结构体类型,长度固定为14个字节。定义如下:

typedef unsigned char LBYTE;
typedef unsigned short LWORD;
typedef unsigned int LDWORD;
typedef long LLONG;         typedef struct
{LWORD bfType;            //位图文件类型,必须是0X4D42LDWORD bfSize;            // 位图文件大小LWORD bfReserved1;        //windows保留字LWORD bfReserved2;        //windows保留字,暂时不用LDWORD bfOffBits;        //从文件头到实际的位图数据的偏移字节数
}LBITMAPFILEHEADER;

二、位图信息头

typedef struct
{LDWORD biSize;            //位图信息头的长度,40字节LLONG biWidth;            //位图的宽度LLONG biHeight;           //位图的高度LWORD biPlanes;           //目标设备级别,必须为1LWORD biBitCount;         // 每个像素所占位数(bit),二值图像为1,灰度图像为8,真彩色图像为24LDWORD biCompression;     //  位图压缩类型LDWORD biSizeImage;       // 实际的位图数据占用的字节数LLONG biXPelsPerMeter;    //指定目标设备的水平分辨率LLONG biYPelsPerMeter;    //指定目标设备的垂直分辨率LDWORD biClrUsed;         // 位图实际用到的颜色数LDWORD biClrImportant;    // 位图显示过程中重要的颜色数
}LBITMAPINFOHEADER;

三、颜色表

颜色表也是一个结构体类型,实际上是一个颜色表结构的数组,数组的长度由biClrUsed指定。其中有些位图需要颜色表,如灰度图;有些位图不需要颜色表,如真彩色图。

typedef struct
{LBYTE rgbBlue;        //蓝色分量LBYTE rgbGreen;       //绿色分量LBYTE rgbRed;         //红色分量LBYTE rgbReserved;    //保留字节,暂时不用
}LRGBQUAD;

四、位图数据

位图数据也就是图像数据,紧跟在位图文件头,位图信息头和颜色表之后,记录了图像的每一个像素值。

需要注意的是,windows规定一个扫描行所占的字节数必须是4的倍数,不足4的倍数则要对其进行扩充。则每个扫描行所占的真实字节数的计算结果为:int lineByte = (imWidth * biBitCount / 8 + 3)/ 4 * 4;

现在是保存图像数据的时候,这里我保存的是灰度图像的数据,所以直接设置biBitCount的值为8。大家可以根据自己的需求进行修改。saveBMP.cpp的代码如下:

#include "StdAfx.h"
#include"bmp.h"
#include<iostream>using namespace std;bool SaveBmp1(char * fileName,unsigned char *imgBuffer, int imWidth, int imHeight)
{if (!imgBuffer){return 0;}int biBitCount = 8;int colorTablesize = 1024;  //灰度图像颜色表int lineByte = (imWidth * biBitCount / 8 + 3)/ 4 * 4;FILE *fp = fopen(fileName, "wb");if (!fp){return 0 ;}LBITMAPFILEHEADER filehead;filehead.bfType = 0x4D42;filehead.bfSize = sizeof(LBITMAPFILEHEADER) + sizeof(LBITMAPINFOHEADER) + colorTablesize + lineByte * imHeight;filehead.bfReserved1 = 0;filehead.bfReserved2 = 0;filehead.bfOffBits = 54 + colorTablesize;//写位图文件头进文件fwrite(&filehead , sizeof(LBITMAPFILEHEADER), 1, fp);//申请位图文件信息头结构变量, 填写文件信息头信息LBITMAPINFOHEADER infoHead;infoHead.biBitCount = biBitCount;infoHead.biClrImportant = 0;infoHead.biClrUsed = 0;infoHead.biSize = 40;infoHead.biWidth = imWidth;infoHead.biHeight = imHeight;infoHead.biPlanes = 1;infoHead.biCompression = 0;infoHead.biSizeImage = lineByte * imHeight;infoHead.biXPelsPerMeter = 0;infoHead.biYPelsPerMeter = 0;fwrite(&infoHead, sizeof(LBITMAPINFOHEADER), 1, fp);//fwrite(&filehead, sizeof(LBITMAPFILEHEADER), 1, fp);LRGBQUAD *pColorTable = new LRGBQUAD[256];for (int i = 0 ; i < 256 ; i++){pColorTable[i].rgbBlue = i;pColorTable[i].rgbGreen = i;pColorTable[i].rgbRed = i;//pColorTable[i].rgbReserved = 0;}fwrite(pColorTable, sizeof(LRGBQUAD), 256, fp);//写位图数据进文件fwrite(imgBuffer, imHeight*lineByte, 1, fp);fclose(fp);return 1;
}
 

bmp.h代码如下:

#ifndef BMP_H
#define BMP_Htypedef unsigned char LBYTE;   //
typedef unsigned short LWORD;   //
typedef unsigned int LDWORD;
typedef long LLONG;             ////#pragma pack(2)
typedef struct
{LWORD bfType;LDWORD bfSize;LWORD bfReserved1;LWORD bfReserved2;LDWORD bfOffBits;
}LBITMAPFILEHEADER;
// #pragma pack(pop)typedef struct
{LDWORD biSize;LLONG biWidth;LLONG biHeight;LWORD biPlanes;LWORD biBitCount;LDWORD biCompression;LDWORD biSizeImage;LLONG biXPelsPerMeter;LLONG biYPelsPerMeter;LDWORD biClrUsed;LDWORD biClrImportant;
}LBITMAPINFOHEADER;typedef struct
{LBYTE rgbBlue;LBYTE rgbGreen;LBYTE rgbRed;LBYTE rgbReserved;
}LRGBQUAD;typedef struct
{unsigned char* buf;int width_x;int height_y;int deepth;LRGBQUAD* palette;
}LBmpbase;//bool saveBmp(char*, unsigned char*, int, int, int, RGBQUAD*);
//Bmpbase readbmp(char*);
bool saveBmp(char*, unsigned char*, int, int, int, LRGBQUAD* );bool SaveBmp1(char * fileName,unsigned char *imgBuffer, int imWidth, int imHeight);bool wDataToBitBmp(BYTE*, int imWidth, int imHeight, char *imName);
// Bmpbasel readbmp(char*);
// Bmpbase imrotate(unsigned char*, int, int, int, RGBQUAD*, double);#endif

下面是我调用SaveBmp1的实例:

SaveBmp1((char *)(LPCTSTR)(strFileName1), pBmpImage, 640, 512);

//strFileName1 为保存的bmp格式图像的图像名, pBmpImage为 unsigned char * 类型的图像数据, 640,512分别为图像宽和高。

保存图像数据为BMP格式的图片相关推荐

  1. JPG、GIF、PNG和BMP格式的图片各有什么优点和缺点

    BMP:优点(无损压缩,图质最好),缺点(文件太大,不利于网络传输) GIF:优点(动画存储格式),缺点(最多256色,画质差) PNG:优点(可保存透明背景的图片),缺点(画质中等) JPG:优点( ...

  2. Android Camera生成bmp格式的图片

    Android Camera拍照默认会生成jpg格式的图片,这是一种有损压缩后的图片格式.前段时间项目需要生成一张无压缩的bmp格式的图片,这就不能通过拍照来实现,而是需要通过预览时的某一帧数据来生成 ...

  3. OpenCV应用:将jpg格式的图片转为bmp格式的图片

    将jpg格式的图片转为bmp格式的图片 之前看到一篇博文,说用cvLoadImage函数读出来的是IplImage类的值,同时cvSaveImage的输入也是IplImage类的值,这就可以通过这两个 ...

  4. Python将bmp格式的图片批量转成jpg

    # *_* coding : UTF-8 *_* # 开发人员: csu·pan-_-|| # 开发时间: 2020/11/21 12:40 # 文件名称: bmp_to_jpg.py # 开发工具: ...

  5. BMP格式的图片怎在线压缩

    BMP格式的图片怎在线压缩,大家在上传图片的时候有没有遇到过"因文件太大,上传失败"的问题,图片太大不仅占用空间,而且十分影响传递,那有没有什么解决方法呢,接下来让小编来告诉大家吧 ...

  6. 医疗dcm格式图像解析成bmp格式图片

    医疗拍摄的dcm格式图像一般不能直观的给我们展示出来,需要使用程序对里面的元素进行解析.一般我们用ViewPersonal软件来查看dcm格式的图像. dcm格式图像解析过程一般如有图所示: 其中dc ...

  7. c语言将两幅bmp格式图片拼接图片

    要将两幅 BMP 格式图片拼接在一起,你需要先打开这两幅图片并读取它们的像素数据.然后,你可以使用每幅图片的像素数据来创建一个新的图像,将两幅图片的像素数据拼接在一起.最后,你可以使用 BMP 文件格 ...

  8. stm32驱动ov7670 数据转BMP格式再转JPEG存储

    一.搞了几天摄像头终于搞出来了一点成果,本打算用BMP格式保存读出的数据但是数据太大达到225k,后来又将BMP数据转成JPEG格式就小了很多,jpeg是有损压缩图片会变得不那么清晰. 搞出来的成果: ...

  9. 给图像数据加上BMP文件头

    需要将摄像头采集到的图像数据(纯净的RGB,或BGR数据)加上文件头后暂存在内存中 如若写入文件仅需将memcpy换成fwrite即可. #ifndef RGB2BMP_H #define RGB2B ...

最新文章

  1. 混合app用百分比还是rem_一次搞懂前端所有CSS长度单位,px、em、rem、rpx、%....
  2. Tomcat中出现“RFC 7230 and RFC 3986“错误的解决方法
  3. js 闭包的用法详解
  4. 【ok】李宏毅机器学习12: 对称矩阵
  5. 严重: StandardServer.await: create[8005]:
  6. go websocket 关闭_Go实战--使用之gorilla/websocket
  7. postman使用过程中body中的form-data,x-www-form-urlencoded,raw,binary的简单记录
  8. 【Swin Transformer Block】的整体流程如下:
  9. centos7-docker-网络配置
  10. 接口返回500一般是什么错_什么情况下?超过了500万元的销售额标准,也不用办理一般纳税人资格认定?...
  11. 详细分析 Sonlogger 任意文件上传漏洞 (CVE-2021-27964)
  12. CDH hive的安装
  13. 彩色静电植绒印花工艺的五个方法
  14. 详解TCP和UDP数据段的首部格式
  15. ocr tesseract_OCR引擎之战— Tesseract与Google Vision
  16. 群体智能优化算法之粒子群优化算法
  17. wireshark抓取分析UDP数据包
  18. [JZOJ6042]【NOI2019五校联考2019.3.5】Second【SA】【分治】
  19. 捷联惯导知识点之非直角坐标系到直角坐标系
  20. 应届生如何写求职邮件?

热门文章

  1. Email的HTML代码模板
  2. Android开发能够帮你更好开发的19个开发工具
  3. Acer 4745系,重装后快捷方式无图标及触控板功能失效
  4. System.currentTimeMillis的性能如何
  5. 简单的爬虫例子——爬取豆瓣Top250的电影的排名、名字、评分、评论数
  6. 工作中常用且容易遗忘的 CSS 样式清单整理
  7. CENTOS7网络时钟同步
  8. 乌镇•白硕:抗衡Libra,我们需要建立一个法定数字货币体系
  9. 2018 kick start roundA A Even_digits
  10. 详解android framework中StateMachine(HSM层次状态机)的实现