关于BMP格式图像的理解和读写(c++).docx
一、什么是BMP格式?
BMP,(全称Bitmap)是Windows操作系统中的标准图像文件格式,可以分成两类:设备相关位图(DDB)和设备无关位图(DIB),使用非常广。它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP 文件所占用的空间很大。BMP文件的图像深度可选1bit、4bit、8bit及24bit。BMP 文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序。由于BMP文件格式是Windows环境中交换与图有关的数据的一种标准,因此在Windows环境中运行的图形图像软件都支持BMP图像格式。二、怎么计算BMP的大小BMP是一种不压缩的图像文件,我们怎么计算bmp图像的大小呢?BMP的类别及存储方式1.BMP的常见类型通常我们最常见的就是24位图,所谓的24位图,就是说一个像素的颜色信息用24位来表示,也就是说,对于三原色BRG,每一个颜色都用以字节(8)位来表示。除了24位图,还有1位(单色),2位(4色,CGA),4位(16色,VGA),8位(256色),16位(增强色),24位(真彩色)和32位等。2. BMP的文件头:BMP文件头(bmp file header):共14字节0-1:bfType,表示文件类型,BMP格式的文件这两个字节是0x4D42,10进制就是19778,字符显示就是‘BM’;
2-5:bfSize,表示文件的大小,检查文件信息,验证正确;
6-7:bfReserved1,保留位,必须设置为0;
8-9:bfReserved2,保留位,必须设置为0;
a-d:bfOffBits,4字节的偏移,表示从文件头到位图数据的偏移;位图信息头(bitmap information):共40字节;0e-11:4字节的biSize, 信息头的大小,即40;
12-15:4字节的biWidth,用像素表示图像的宽度,查看文件信息验证正确;
16-19:4字节的biHeight,以像素为单位说明图像的高度,同时如果为正,说明位图倒立(即数据表示从图像的左下角到右上角),如果为负说明正向; (这两个信息在程序要在内存分配的时候使用)
1a-1b:2字节的biPlanes,为目标设备说明颜色平面数,总被设置为1;
1c-1d:2字节的biBitCount,说明比特数/像素数,值有1、2、4、8、16、24、32;
1e-21:4字节的biCompression,说明图像的压缩类型,最常用的就是0(BI_RGB),表示不压缩;
22-25:4字节的biSizeImage,说明位图数据的大小,当用BI_RGB格式时,可以设置为0;
26-29:4字节的biXPelsPerMeter,表示水平分辨率,单位是像素/米,有符号整数;
2a-2d:4字节的biYPelsPerMeter,表示垂直分辨率,单位是像素/米,有符号整数;
2e-31:4字节的biClrUsed,说明位图使用的调色板中的颜色索引数,为0说明使用所有;
32-35:4字节的biClrImportant,说明对图像显示有重要影响的颜色索引数,为0说明都重要;
所以,总的BMP格式从头到尾的顺序应该是:
a. bmp文件头(bmp file header):共14字节;
b. 位图信息头(bitmap information):共40字节;
c. 调色板(color palette):可选;
d. 位图数据;计算大小假设我们获取的是每个像素是24位的bmp图像,即每个像素占用三个字节(按照R、G、B的顺序,每个分量占一个字节),此外,这种格式还需要54个额外的字节来存储“头”信息,可以根据以下公式确定BMP文件大小:
Hbytes=(Hpixels*3+3) & (11.......00)
24b RGB BMP文件大小= 54 + Hbytes*Vpixels
其中Vpixels和Hpixels是图像的高度和宽度,(这里V是指vertical,H是指horizon,与一般width和high表示方式要区别开,如果是640×480的图片,就是对应Vpixels=480, Hpixels=640),则图片大小为:
54+3×640×480=921654 bytes。
但是看公式,可以知道Hbytes必须舍入为下一个可以被4整除的整数,以确保BMP图像大小是4的倍数。为什么要确保BMP图像大小是4的倍数?1.首先普及一个概念,什么是32位系统、64位系统?32位和64位操作系统是指:CPU一次处理数据的能力是32位还是64位。现在市场上的CPU一般都是64位的,但是这些CPU并不是真正意义上的64 位CPU,里面依然保留了大部分32位的技术,只是进行了部分64位的改进。32位和64位的区别还涉及了内存的寻址方面,32位系统的最大寻址空间是2 的32次方= 4294967296(bit)= 4(GB)左右,而64位系统的最大寻址空间的寻址空间则达到了2的64次方= 4294967296(bit)的32次方=数值大于1亿GB。换而言之,就是说32位系统的处理器最大只支持到4G内存,而64位系统最大支持的内存高达亿位数。2.网上最多的解释位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是左到右,扫描行之间是从下到上。位图的一个像素值所占的字节数:
当biBitCount(每个像素所需的位数)=1时,8个像素占1个字节;
当biBitCount=4时,2个像素占1个字节;
当biBitCount=8时,1个像素占1个字节;
当biBitCount=24时,1个像素占3个字节;
Windows规定一个扫描行所占的字节数必须是4的倍数(即以long为单位),不足的以0填充。
3.举个例子如果是24位1024×1024的BMP文件需要的存储空间为:
54+1024*1024*3 = 3145782字节
如果是24位321×1024的BMP文件需要的存储空间为:
54+(321*3+1)*127 = 122482字节
相当于需要每行要浪费一个字节,总共需要浪费127个字节。
三、怎么读取bmp格式的图片
#include "ImageStuff.h"unsigned char **ReadBMP(char *filename) {int i;FILE *f = fopen(filename, "rb");if (f == NULL) {printf("\n\n%s NOT FOUND\n\n", filename);exit(1);}unsigned char HeaderInfo[54];fread(HeaderInfo, sizeof(unsigned char), 54, f); // read the 54-byte header// extract image height and width from headerint width = *(int *) &HeaderInfo[18];int height = *(int *) &HeaderInfo[22];//copy header for re-usefor (i = 0; i < 54; i++) { ip.HeaderInfo[i] = HeaderInfo[i]; } ip.Vpixels = height; ip.Hpixels = width; int RowBytes = (width * 3 + 3) & (~3);//Be careful with this! ip.Hbytes = RowBytes; printf("\n Input BMP File name: %20s (%u x %u)", filename, ip.Hpixels, ip.Vpixels); unsigned char tmp; unsigned char **TheImage = (unsigned char **) malloc(height * sizeof(unsigned char *)); for (i = 0; i < height; i++) { TheImage[i] = (unsigned char *) malloc(RowBytes * sizeof(unsigned char)); } for (i = 0; i < height; i++) { fread(TheImage[i], sizeof(unsigned char), RowBytes, f); } fclose(f); return TheImage; // remember to free() it in caller!
四、怎么写入bmp格式的图片
void WriteBMP(unsigned char **img, char *filename) {FILE *f = fopen(filename, "wb");if (f == NULL) {printf("\n\nFILE CREATION ERROR: %s\n\n", filename);exit(1);}unsigned long int x, y;char temp;//write headerfor (x = 0; x < 54; x++) { fputc(ip.HeaderInfo[x], f); } //write data for (x = 0; x < ip.Vpixels; x++) { for (y = 0; y < ip.Hbytes; y++) { temp = img[x][y]; fputc(temp, f); } } printf("\n Output BMP File name: %20s (%u x %u)", filename, ip.Hpixels, ip.Vpixels); fclose(f); }
对应的头文件 ImageStuff.h:
#include
#include
#include
struct ImgProp {int Hpixels;int Vpixels;unsigned char HeaderInfo[54];unsigned long int Hbytes;
};
struct Pixel {unsigned char R;unsigned char G;unsigned char B;
};
unsigned char **ReadBMP(char *);
void WriteBMP(unsigned char **, char *);
extern struct ImgProp ip;
备注:
点击下面链接,进入奥比中光开发者社区,了解更多3D视觉技术信息:
https://developer.orbbec.com.cn/
或扫描下方二维码,进入奥比中光开发者社区:
关于BMP格式图像的理解和读写(c++).docx相关推荐
- 数字图像处理:关于BMP格式图像的理解和读写(c++)
一.什么是BMP格式? 它与我们常见的其他图片格式(jpeg, jpg, png, tif)有什么区别? 1.JPEG JPEG是Joint Photographic Experts Group(联合 ...
- bmp 格式图像印刷体数字的识别
一.实验目的 初步了解模板匹配算法,理解bmp 图像在内存中的存储形式,实现bmp 格式图像印刷体数字的识别. 二.算法概要 由于实验要求是对标准印刷体数字进行识别,本实验采用模板匹配中最简单的像素点 ...
- BMP格式图像知识点总结并转灰度图
24位彩图转换为灰度图练习 练习目的 位图知识点 BMP图像存储结构 位图文件头 位图信息头 调色板 位图数据 转灰度图重点 代码例程 练习目的 BMP格式图片灰度化 位图知识点 刚拿到任务时觉得图像 ...
- jpg、png及bmp格式图像的区别
图像处理:JPG.PNG及BMP的区别? 1.JPG: 全名应该是JPEG,JPEG 图片以 24 位颜色存储单个光栅图像(RGB),支持最高级别的压缩,不过,这种压缩是有损耗的.可以提高或降低 JP ...
- BMP格式图像的显示
使用多文档编程 也可以使用单文档编程 建立一个DIB图像的显示类 ImageDib 成员变量: 4个指针: LPBYTE m_lpDib; //指向DIB的指针 LPBITMAPINFOHE ...
- FFmpeg开发实战(五):bmp转换为jpeg格式图像
文章目录 1. bmp结构 2. bgr24转yuv420p 3. yuv420转jpeg 4. 下载 本文介绍了将bmp格式图像转换为jpeg格式图像的方法,附有详细的代码和图像示例. 1. bmp ...
- 保存图像数据为BMP格式的图片
BMP文件是Windows操作系统所推荐和支持的图像文件格式,是一种将内存或显示器的图像数据不经过压缩而直接按位存盘的文件格式,所以称为位图(bitmap)文件. BMP文件结构 BMP图像文件包括四 ...
- 【数字图像处理】一.MFC详解显示BMP格式图片
本文主要是讲述<数字图像处理>系列栏目中的第一篇文章.主要详细介绍了BMP图片格式,同时使用C++和MFC显示BMP格式,主要结合自己的<数字图像处理>课程和以前的项目叙述讲解 ...
- MFC详解显示BMP格式图片
本文主要是讲述<数字图像处理>系列栏目中的第一篇文章.主要详细介绍了BMP图片格式,同时使用C++和MFC显示BMP格式,主要结合自己的<数字图像处理>课程和以前的项目叙述讲解 ...
最新文章
- 不讲码德!坏味道偷袭我这个老码农
- TensorFlow、Numpy中的axis的理解
- 随机数据的构造与使用
- win10+vscode部署java开发环境
- 修改eclipse或者myeclipse的背景颜色(全部的背景颜色)
- 透视特洛伊木马程序开发技术(转)
- U盘不识别量产工具解决方案
- 经纬度转XY坐标-批量转换
- ROMS 编译upwelling.h
- xp计算机无法关机,WindowsXP电脑无法关机?6招轻松解决故障
- 【科学文献计量】中英文文献标题及摘要分词字数与频数统计与可视化
- NVivo更改背景字体
- 支持向量机_4:Outliers
- 【游戏逆向】某某明月刀_技能冷却分析
- 学习笔记之——Semi-direct Visual Odometry (SVO)
- 我们的指纹是如何形成的,科学家找到主导指纹形成原因
- 微信内嵌H5网页 解决js倒计时失效
- 【PP-6】新建物料清单BOM
- 【T3】打印单据(非新打印)表头显示不全
- C语言--第三次作业