BMP位图文件的存储格式

2024-02-10 06:18
文章标签 存储 格式 bmp 位图文件

本文主要是介绍BMP位图文件的存储格式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

摘  要:本文简单介绍了位图文件的两种存储格式,并且在VC++6.0下实现了读取位图文件中的数据,用SetPixel()函数在窗口中重现图像,最后在程序中实现了一种存储格式到另一种存储格式的转换。

关键字:BMP、灰度位图、24位真彩色位图、存储格式

一、前言

BMP(Bitmap的缩写)图像是指文件名后缀为BMP的位图图像。位图图像在计算机中使用很广泛,例如在windows中,记事本、写字板中的文字就是用位图图像表示出来的。许多以其它格式存储的图像,就是在位图图像的基础上,进行优化处理后得到的,例如JPEG图像等。

    在数字图像处理中,许多算法就是针对24位真彩色位图或灰度位图设计的。因此,很有必要介绍一下位图文件的这两种存储格式。

二、24位真彩色图像存储格式

把下图的24位真彩色图像格式在16位编辑器(例如VC编辑器)中打开,可以看到图像的二进制数据。


 

24位真彩色的二进制数据为:


    这是24位真彩色位图文件数据一部分。这一部分数据包括位图文件头、位图信息头和位图阵列三部分。

    (一)位图文件头

    位图文件头用来记录标志文件大小的一些信息,在文件中占14个字节,存储的内容如下:

字节
 
 1
 2
 3
 4
 5
 6
 7
 8
 
 9
 10
 11
 12
 13
 14
 
000000
 
 42
 4D
 CC
 B4
 02
 00
 00
 00
 
 00
 00
 36
 00
 00
 00
 

其中:

42 4D          为位图的标志,即ASCII码为BM

CC B4 02        表示位图文件的总字节数,换算成十进制为(02B4CC)H=(177356)10,即这副图像的大小为177356字节。

00 00 00 00 00 为保留字节,用来存储文件大小的数据。

36 00 00 00 00 表示位图阵列的起始位置,(36)H=(54)10即54字节开始为位图阵列。

(二) 位图信息头

位图信息头记录和位图相关的一些信息,在文件中占40个字节,存储的内容如下:

字节
 
 1
 2
 3
 4
 5
 6
 7
 8
 
 9
 10
 11
 12
 13
 14
 15
 16
 
000000
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 28
 00
 
000016
 
 00
 00
 2C
 01
 00
 00
 C5
 00
 
 00
 00
 01
 00
 18
 00
 00
 00
 
000032
 
 00
 00
 00
 00
 00
 00
 12
 0B
 
 00
 00
 12
 0B
 00
 00
 00
 00
 
000048
 
 00
 00
 00
 00
 00
 00
 
 
 
 
 
 
 
 
 
 
 
 

其中:

28 00 00 00  表示信息头的长度,(28)H=(40)10,即位图信息头占40个字节。

2C 01 00 00   表示位图宽度,单位为像素。(012C)H=(300)10,即位图的宽度为300个像素。

C5 00 00 00  表示位图高度,单位为像素。(C5)H=(197)10,即位图的宽度为197个像素。

01 00        表示位图设备级别

18 00        位图级别,(0018)H=(24)10,即24位真彩色。

00 00 00 00  表示压缩类型,为零表示不压缩。

00 00 00 00  保留字节。

12 0B 00 00  表示水平分辨率

12 0B 00 00  表示垂直分辨率

00 00 00 00  表示位图实际使用的颜色表中的颜色变址数。

00 00 00 00  表示位图显示过程中被认为重要颜色变址数。

(三)位图像素阵列

    剩下的部分为位图像素阵列,即像素表示部分,每个象素点由3个字节的数据组成,按照从左到右的顺序,分别表示蓝色、绿色、红色。

    在VC++中的wingdi.h中对于位图的编码和格式有更加详细的定义,下面给出24位真彩色位图格式在VC++中的定义。

typedef struct tagBITMAPFILEHEADER {//位图文件头

WORD bfType; //位图标志“BM”

DWORD bfSize; //位图文件总字节数

WORD bfReserved1;

WORD bfReserved2;

DWORD bfOffBits;

} BITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER{ //位图信息头格式定义

DWORD biSize; //位图信息头占用字节数

LONG biWidth; //位图图像宽度(以像素为单位)

LONG biHeight; //位图图像高度(以像素为单位)

WORD biPlanes; //位图设备级别

WORD biBitCount //位图级别设定,每个像素所需的位数,必须是1(双色),
                // 4(16色),8(256色)或24(真彩色)之一

DWORD biCompression; //压缩类型

DWORD biSizeImage; //位图阵列表字节数

LONG biXPelsPerMeter; //水平分辨率

LONG biYPelsPerMeter; //垂直分辨率

DWORD biClrUsed; //位图实际使用的颜色表中的颜色变址数

DWORD biClrImportant; //位图显示过程中被认为重要颜色变址数

} BITMAPINFOHEADER;

typedef struct tagRGBTRIPLE { //位图阵列格式定义

BYTE rgbtBlue; //定义蓝色

BYTE rgbtGreen; //定义绿色

BYTE rgbtRed; //定义红色

} RGBTRIPLE;//构成一个3字节的RGBTRIPLE。

按照这个这个结构可以从BMP文件中读取数据,然后在屏幕上用SetPixel()函数描绘出来。主要代码如下:

if (!cf.Open(TransValue,CFile::modeRead, &e))//找到文件后,打开文件

{

    MessageBox("Can not open the file!","Open File");

    return;

}

cf.SeekToBegin();

cf.Read(&bmfh,sizeof(bmfh));//读取文件头

cf.Read(&bmih,sizeof(bmih));//读取文件信息头

rgb = new RGBTRIPLE[bmih.biWidth*bmih.biHeight];

cf.SeekToBegin();

cf.Seek(54,CFile::begin);

//读取文件数据

if (cf.GetLength()>64*1024)

{

    cf.ReadHuge(rgb,bmih.biWidth*bmih.biHeight*3);//

}

else

{

    cf.Read(rgb,bmih.biWidth*bmih.biHeight);

}

//在屏幕上打点显示图像

for (int i=0; i<bmih.biHeight;i++)

{

    for (int j=0; j<bmih.biWidth; j++)

    {

    pDC->SetPixel(j,bmih.biHeight-i,RGB(rgb[i*bmih.biWidth+j].rgbtRed,rgb[i*bmih.biWidth+j].rgbtGreen,rgb[i*bmih.biWidth+j].rgbtBlue));

    }

}

cf.Close();//关闭文件

delete rgb;//释放内存

三、灰度位图存储格式

同样,把下面的灰度位图在VC编辑器中以Binary方式打开,可以看到如下的数据(部分):


灰度位图数据:


    从上述数据中可以看出,灰度位图的存储格式与24位真彩色位图的存储格式基本相同。唯一的差别是,灰度位图比24位真彩色位图增加了一部分:颜色索引表。因此,灰度位图的像素阵列的起始位置不是第(36)H=(54)10个字节,而是第(436)H=(1078)10个字节,同时灰度位图用一个字节来表示一个像素。这样,灰度位图的像素阵列小了三分之二。

    颜色索引表定义为:

typedef struct rgbn
{
BYTE red;
BYTE green;
BYTE blue;
BYTE null;
} RGBn;
在实际的编程中,读取数据的方式发生了变化,除了要读取文件头,文件信息头外,还要设置变量读取颜色索引表。除此以外,灰度图像的编程读取显示方式与24位真彩色位图的方式完全相同,在此就不再描述。

从上述灰度位图和24位真彩色位图的存储结构中可以看出,把24位真彩色位图的颜色信息去掉,就可以得到灰度位图。根据不同的需要,不同的理论,有不同的去掉颜色的方法。在本文中,仅仅在红、绿、蓝三种基本色前加权三分之一,然后在屏幕上打点显示出来,得到灰度位图图像。如果需要存储,只需要在文件头、文件信息头后加上颜色索引表,然后再以一个字节的空间存储位图像素信息,把上述信息按顺序写到一个文件中,就得到一个灰度位图图像文件。  

这篇关于BMP位图文件的存储格式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/696343

相关文章

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

HDFS—存储优化(纠删码)

纠删码原理 HDFS 默认情况下,一个文件有3个副本,这样提高了数据的可靠性,但也带来了2倍的冗余开销。 Hadoop3.x 引入了纠删码,采用计算的方式,可以节省约50%左右的存储空间。 此种方式节约了空间,但是会增加 cpu 的计算。 纠删码策略是给具体一个路径设置。所有往此路径下存储的文件,都会执行此策略。 默认只开启对 RS-6-3-1024k

easyui同时验证账户格式和ajax是否存在

accountName: {validator: function (value, param) {if (!/^[a-zA-Z][a-zA-Z0-9_]{3,15}$/i.test(value)) {$.fn.validatebox.defaults.rules.accountName.message = '账户名称不合法(字母开头,允许4-16字节,允许字母数字下划线)';return fal

速了解MySQL 数据库不同存储引擎

快速了解MySQL 数据库不同存储引擎 MySQL 提供了多种存储引擎,每种存储引擎都有其特定的特性和适用场景。了解这些存储引擎的特性,有助于在设计数据库时做出合理的选择。以下是 MySQL 中几种常用存储引擎的详细介绍。 1. InnoDB 特点: 事务支持:InnoDB 是一个支持 ACID(原子性、一致性、隔离性、持久性)事务的存储引擎。行级锁:使用行级锁来提高并发性,减少锁竞争

[数据集][目标检测]血细胞检测数据集VOC+YOLO格式2757张4类别

数据集格式:Pascal VOC格式+YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):2757 标注数量(xml文件个数):2757 标注数量(txt文件个数):2757 标注类别数:4 标注类别名称:["Platelets","RBC","WBC","sickle cell"] 每个类别标注的框数:

一步一步将PlantUML类图导出为自定义格式的XMI文件

一步一步将PlantUML类图导出为自定义格式的XMI文件 说明: 首次发表日期:2024-09-08PlantUML官网: https://plantuml.com/zh/PlantUML命令行文档: https://plantuml.com/zh/command-line#6a26f548831e6a8cPlantUML XMI文档: https://plantuml.com/zh/xmi

ORACLE语法-包(package)、存储过程(procedure)、游标(cursor)以及java对Result结果集的处理

陈科肇 示例: 包规范 CREATE OR REPLACE PACKAGE PACK_WMS_YX IS-- Author : CKZ-- Created : 2015/8/28 9:52:29-- Purpose : 同步数据-- Public type declarations,游标 退休订单TYPE retCursor IS REF CURSOR;-- RETURN vi_co_co

OpenStack离线Train版安装系列—11.5实例使用-Cinder存储服务组件

本系列文章包含从OpenStack离线源制作到完成OpenStack安装的全部过程。 在本系列教程中使用的OpenStack的安装版本为第20个版本Train(简称T版本),2020年5月13日,OpenStack社区发布了第21个版本Ussuri(简称U版本)。 OpenStack部署系列文章 OpenStack Victoria版 安装部署系列教程 OpenStack Ussuri版

多云架构下大模型训练的存储稳定性探索

一、多云架构与大模型训练的融合 (一)多云架构的优势与挑战 多云架构为大模型训练带来了诸多优势。首先,资源灵活性显著提高,不同的云平台可以提供不同类型的计算资源和存储服务,满足大模型训练在不同阶段的需求。例如,某些云平台可能在 GPU 计算资源上具有优势,而另一些则在存储成本或性能上表现出色,企业可以根据实际情况进行选择和组合。其次,扩展性得以增强,当大模型的规模不断扩大时,单一云平

MySQL技术内幕_innodb存储引擎

MySQL技术内幕_innodb存储引擎 INNODB innodb中如果表没有主键 表是否由 非空唯一键,有则该字段为主键没有,则自动创建一个6字节大小的指针 innodb存储引擎的所有数据都存储在表空间中,表空间由段,区,页(块)组成。 如果启用了 innodb_file_per_table, 则每张表内的数据可以单独放在一个表空间中即使启用了上面参数,共享表空间也会因为 系统事务信息