文章目录
- 一、BMP位图简介
- 二、BMP格式分析
-
- 2.1 如何用十六进制打开BMP图片
- 2.2 头文件格式
- 2.3 信息头格式
- 2.4 调色板格式
- 2.5 位图数据格式
- 2.6 位图对齐方式
- 三、Verilog图像处理的仿真环境搭建
-
- 3.1 Verilog文件操作指令
-
- 3.1.1 条件编译 (`` `ifdef``、 `` `else``、`` `endif``)
- 3.1.2 文件打开($fopen)
- 3.1.3 文件关闭($fclose)
- 3.1.4 文件写入($fwrite)和(fdisplay)
- 3.1.5 文件读取
- 3.1.6 文件定位
- 3.2 读写BMP图片仿真环境搭建
-
- 3.2.1 宏定义标识符以及条件编译例化
- 3.2.2 常量和变量的声明
- 3.2.3 寄存器和wire声明
- 3.2.4 初始化R、G、B、以及BMP头文件寄存器的值
- 3.2.5 从RGB寄存器中读出RGB像素值,再生成对应时序
- 3.2.5 整体仿真流程控制
- 3.2.6 写新的BMP图像
- 四、仿真结果观察
一、BMP位图简介
扩展名为 .BMP(Bitmap Image File)格式是一种位图图像文件格式,用于存储图像数据。它由微软在1986年推出,广泛用于Windows操作系统中。位图按照是否与设备相关分类可以分为:设备相关位图DDB(device-dependent bitmap)、设备无关位图DIB(device-independent bitmap)。BMP格式的特点包括:
-
无压缩:BMP文件通常以未压缩的形式存储图像数据,这意味着图像质量较高,但文件大小也相对较大。
-
简单的结构:BMP文件的结构相对简单,包含文件头、信息头、调色板(可选)和像素数据等部分。
-
支持多种颜色深度:BMP格式支持多种颜色深度,从1位(黑白)到32位(包含透明度),这使得它可以存储不同类型的图像。
-
兼容性:由于其简单性和历史悠久,BMP格式在许多图像处理软件和操作系统中具有良好的兼容性。
-
缺乏压缩:虽然这使得图像质量保持较高,但也导致了文件体积较大,不适合网络传输。
位深度又叫色彩位数,即位图中要用多少个二进制位来表示每个点的颜色,是分辨率的一个重要指标。常用有1位(单色),2位(4色,CGA),4位(16色,VGA),8位(256色),16位(增强色),24位(真彩色)和32位(增强型真彩色)等。
例如我电脑上这张BMP图片,分辨率是1920*1280,位深度是24位。
二、BMP格式分析
BMP结构相对简单,主要由以下几个部分组成:文件头、信息头、调色板(可选)、位图数据四部分组成 。
2.1 如何用十六进制打开BMP图片
我们随便双击打开一张BMP图片显示如下:
这是一张1920*1280,24位深的BMP图片,接下来我们想要用文本编辑器查看这图片的存储数据:
- 我电脑上装的是notepad++,打开notepad++点击右上角的插件管理:
- 搜索Hex-Editor,然后点击安装
- 安装后notepad++会重启,此时我们点击BMP图片,打开方式选择notepad++
- 此时我们看现在还是显示乱码,我们点击右上角的插件 -> Hex-Editor - > View in HEX
此时我们的BMP图片就以16进制的格式打开了,接下来我们分析BMP文件格式。
2.2 头文件格式
文件头包含了关于文件的基本信息,包括文件类型、文件大小、保留字段和偏移量等。文件头的前两个字节通常是字符“BM”,表示这是一个BMP文件;一共占用14个字节,文件头的结构体定义如下所示:
typedef struct tagBITMAPFILEHEADER{
WORD bftype; // 位图文件的类型,必须设置为BM,占用2字节
DWORD bfSize; // 位图文件的大小,以字节为单位,占用4字节
WORD bfReserved1; // 位图文件保留字,必须设置为0,占用2字节
WORD bfReserved2; // 位图文件保留字,必须设置为0,占用2字节
DWORD bfoffBits; // 位图数据相对于位图文件头的偏移量表示,占用4字节
} BITMAPFILEHEADER;
头文件结构体中不同变量说明如下:
变量名称 | 地址偏移(十六进制) | 大小(byte) | 说明 |
bftype | 16'h0000 | 2 | 用于文件的类型,为十六进制的 0x42,0x4D,与 ASCII 中的 B,M 相同,表示文件格式为BMP;它可能有以下值: BM - Windows 3.1x、95、NT、…等 BA - OS/2 结构位图数组 CI - OS/2 结构颜色图标 CP – OS/2 常量颜色指针 IC – OS/2 结构图标 PT – OS/2 指针 |
bfSize | 16'h0002 | 4 | BMP 文件的大小 |
bfReserved1 | 16'h0006 | 2 | 保留 |
bfReserved2 | 16'h0008 | 2 | 保留 |
bfoffBits | 16'h000A | 4 | 位图数据的起始地址,即:可以找到位图图像数据(像素)的字节的偏移量 |
我们用十六进制打开上面的BMP图片分析头文件:
整个红色框中就是14个字节的头文件信息,其中
- 绿色框中的两个字节为0X42,0X4d表示文件类型,分别对应了ASCII表中的’ B ‘,’ M ’
- 蓝色框中的四个字节表示文件的大小(低位在前),这里是0x708036;对应的十进制数就是7372854,说明此图片的大小为7372854字节,我们打开图片属性查看,图像大小就是7372854字节:
-
两个粉色框中的四个字节表示为保留选项,默认为0
-
黑色框中的四个字节表示位图像素的起始地址,这里为0x36 换算成十进制就是54,说明实际像素位置是从54字节开始(头文件14字节+ 信息头40字节 ),有的BMP文件还有调色板,因此像素的起始地址还要在54字节再加上包含调色板信息的字节数。
调色板的主要作用是将像素值映射到实际的颜色。对于低位深度的图像(如1位、4位和8位),每个像素值并不直接表示颜色,而是通过调色板中的索引来找到对应的颜色。BMP格式中包含调色板的情况主要与图像的颜色深度有关:
- 1位色深:每个像素用1位表示,只有两种颜色(黑和白)。此时,调色板会包含2种颜色的定义
- 4位色深:每个像素用4位表示,可以支持16种颜色。调色板将包含这16种颜色的定义
- 8位色深:每个像素用8位表示,可以支持256种颜色。调色板定义了这256种颜色的具体值
在24位和32位色深的情况下,图像的每个像素直接使用RGB值表示颜色,因此不需要调色板。总之,BMP文件会在1位、4位和8位颜色深度的情况下包含调色板,而在24位和32位颜色深度时则不需要调色板。调色板的存在使得低位深度图像能够以较小的文件大小存储多种颜色的信息
2.3 信息头格式
BMP信息头,包含了图像尺寸、像素数据大小、压缩类型、分辨率等信息一共占用40个字节,信息头的结构体定义如下所示:
typedef struct WINBMPINFOHEADER
{
unsigned long biSize; // 信息头结构所需要的字数,占用4字节
unsigned long biWidth; // 图像宽度,单位为像素,占用4字节
unsigned long biHeight; // 图像高度,单位为像素,负数,则说明图像是正向的,占用4字节
unsigned short biPlanes; // 为目标设备说明位面数,其值将总是被设为1,占用2字节
unsigned short biBitCount; // 一个像素占用的bit位,值位1、4、8、16、24、32,占用2字节
unsigned long biCompression; // 压缩类型 占用4字节
unsigned long biSizeImage; // 位图数据的大小,以字节为单位,占用4字节
unsigned long biXPelsPerMeter; // 水平分辨率,单位 像素/米 占用4字节
unsigned long biYPelsPerMeter; // 垂直分辨率,单位 像素/米 占用4字节
unsigned long biClrUsed; // 位图实际使用的颜色表中的颜色变址数 占用4字节
unsigned long biClrImportant; // 位图显示过程中被认为重要颜色的变址数 占用4字节
} WINBMPINFOHEADER;
信息头结构体中不同变量说明如下:
变量名称 | 地址偏移(十六进制) | 大小(byte) | 说明 |
biSize | 16'h000E | 4 | BMP 信息头总体占用的字节数 |
biWidth | 16'h0012 | 4 | 图像宽度,像素为单位 |
biHeight | 16'h0016 | 4 | 图像高度,像素为单位;为正数说明像素是倒序存放,为负数说明像素是正序存放,大多数都是倒叙存放,因此次数大多数是正数 |
biPlanes | 16'h001A | 2 | 色彩平面数,其值始终为1 |
biBitCount | 16'h001C | 2 | 一个像素所占的bit数 |
biCompression | 16'h001E | 4 | 说明图像的压缩的类型,取值范围: 0:BI_RGB(表示无压缩) 1:BI_RLE8(8位RLE压缩) 2:BI_RLE4(4位RLE压缩) 3:BI_BITFIELDS(位字段压缩) 4:BI_JPEG(位图按照JPEG压缩) 5:BI_PNG(位图按照PNG压缩) |
biSizeImage | 16'h0022 | 4 | 图像像素数据的总大小(以字节为单位)。如果使用BI_RGB压缩,则该值可以为零 |
biXPelsPerMeter | 16'h0026 | 4 | 水平分辨率,像素/米 |
biYPelsPerMeter | 16'h002A | 4 | 垂直分辨率,像素/米 |
biClrUsed | 16'h002E | 4 | 调色板颜色索引数,0表示使用所有可能的颜色。 |
biClrImportant | 16'h0032 | 4 | 重要影响的颜色索引数目,0表示所有颜色都重要 |
我们继续用十六进制打开上面的BMP图片分析信息头:
- 红色框中就是4个字节表示整个信息头所占用的大小,这里是0x28,换算成十进制就是40,说明整个信息头占用40个字节。
- 橙色框中4个字节表示图片宽度(单位像素),这里是0x0780,换算成十进制就是1920:
3. 黄色框中4个字节表示图片高度(单位像素),这里是0x0500,换算成十进制就是1280:
- 绿色框中2个字节表示色彩平面数,其值始终为1
- 浅蓝色框中2个字节表示一个像素所占的bit数,这里是0x0018,换算成十进制就是24:
6. 深蓝色框中4个字节表示图像压缩类型,此处为0表示不压缩
7. 紫色框中4个字节表示像素数据的总大小,这里是0x708000,转换成十进制是7372800字节,和头文件中的BMP大小7372854字节,相差54个字节(14个字节的头文件+40个字节的信息头)
8. 粉色框中4个字节表水平分辨率,这里是0x0ec4,转换成十进制是3780像素/米
9. 浅黄色框中4个字节表垂直分辨率,这里是0x0ec4,转换成十进制是3780像素/米
10. 第十个框和第十一个框是调色板相关的参数,我们是24位位图,不包含调色板信息,因此这里都是0:表示使用所有可能的颜色。
2.4 调色板格式
BMP 调色板用于指定显示设备中每个像素颜色的 RGB 值。当调色板存在时(如1位、4位或8位深度的BMP图像),位图数据中的每个像素存储一个用作调色板索引的值,必须通过在调色板中查表才能得到各个像素的颜色数值。调色板通常在图像数据之前存储,调色板的结构体定义如下所示:
typedef tagRGBQUAD{
BYTE rgbBlue; // 蓝色分量
BYTE rgbGreen; // 绿色分量
BYTE rgbRed; // 红色分量
BYTE rgbReserved; //透明度,一般保留
} RGBQUAD;
调色板存放的是一副图像能使用的所有颜色组合,每种颜色占有四个字节B、G、R、A(透明度),例如红色就是:0X0000FF00。调色板的大小与位图色深N有关:
调色板大小 = 2 N 调色板大小=2^N 调色板大小=2N</