Bmp图片格式介绍
Bmp图片格式介绍
介绍
BMP是英文Bitmap(位图)的简写,它是Windows操作系统中的标准图像文件格式,能够被多种Windows应用程序所支持。随着Windows操作系统的流行与丰富的Windows应用程序的开发,BMP位图格式理所当然地被广泛应用。这种格式的特点是包含的图像信息较丰富,几乎不进行压缩,但由此导致了它与生俱来的缺点–占用磁盘空间过大
文件数据结构
bmp 格式图片的文件头长度绝大多数都是 54 字节,其中包括 14 字节的 位图文件头(head)以及 40 字节的 DIB (Device Independent Bitmap) 位图信息数据头(BItmap Information Header)。
位图文件头(14 bytes)
地址(hex) | 字节长度(byte) | 描述 |
---|---|---|
00 | 2 | 固定头文件字段,内容为0x424D |
02 | 4 | bmp文件大小(little endian) |
06 | 2 | 预留字段 |
08 | 2 | 预留字段 |
0A | 4 | 图片信息的开始位置 |
位图信息数据头(40bytes)
地址(hex) | 字节长度(byte) | 描述 |
---|---|---|
0E | 4 | 位图信息数据头的大小 40bytes |
12 | 4 | 图像宽度(little endian) |
16 | 4 | 图像高度(little endian) |
1A | 2 | 色彩平面的数量,默认为1 |
1C | 2 | 每像素用多少bit表示 |
1E | 4 | 图片采用的压缩方式,通常不压缩即BL_RGB,对应值0 |
22 | 4 | 图片大小(原始位图数据大小)对于不压缩的图片,默认为0 |
26 | 4 | 横向分辨率(像素/米) |
2A | 4 | 纵向分辨率(像素/米) |
2E | 4 | 调试板中颜色数量,默认为0 |
32 | 4 | 重要颜色的数量,默认为0 |
原始位图数据 Raw Bitmap Data
拿最常见的 24BPP RGB (24 比特每像素,红绿蓝三通道) 位图来说,每种颜色需要 8 比特,或者说 1 字节,来存储。在二进制文件中,通常情况下,RGB 按照蓝、绿、红的顺序依次表示图片中的像素点,而 RGBA 则按照蓝、绿、红、透明的顺序(从左下开始,横向逐行向上扫描)。特殊时候,也会出现顺序与上述情况不同的特例,这时色彩顺序会写在 DIB Header 的 Bit Fields 中,以不同色彩通道的 Mask 的形式进行规定。由于 BI_BITFIELDS 也是一种压缩方式,而通常 BMP 不采用任何压缩方式,所以绝大多数时候,我们都是按照前面说的顺序进行排序。
地址(hex) | 字节长度(byte) | 描述(big endian) | |
---|---|---|---|
36 | 4 | 00 00 FF 00 | Red Channel bit mask |
3A | 4 | 00 FF 00 00 | Green Channel bit mask |
3E | 4 | FF 00 00 00 | Blue Channel bit mask |
42 | 4 | 00 00 00 FF | Alpha Channel bit mask |
主流的 CPU 每次从内存中读取并处理数据块(chunk),且通常为 32 比特(4 字节)。因此,为了提升读取效率,位图每行的数据(字节)都需要是 4 的倍数,字节对齐
Row_Size = (BitPerPixel * Image_Width + 31) / 32 * 4
每行的字节数等于:每像素比特数乘以图片宽度加 31 的和除以 32,并向下取整,最后乘以 4。
Pix_Array_Size = Row_Size * Image_Height
原始位图数据大小等于:每行的字节数乘以图像高度(也就是总行数)
文件大小 = 原始位图数据大小 + 文件头大小
代码表示bitmap数据
BitMap Head
#pragma pack(1)
typedef struct {unsigned short bfType; // "BM"unsigned int bfSize; // 文件大小unsigned short bfReserved1; // 保留,必须设置为0unsigned short bfReserved2; // 保留,必须设置为0unsigned int bfOffBits; // 从文件头到像素数据的偏移
} BitMapFileHeader;
BitMap Info Header
typedef struct{unsigned int biSize; // 此结构体的大小int biWidth; // 图像的宽int biHeight; // 图像的高unsigned short biPlanes; // 表示bmp图片的平面属,显然显示器只有一个平面,所以恒等于1unsigned short biBitCount; // 一像素所占的位数,一般为24unsigned int biCompression; // 说明图象数据压缩的类型,0为不压缩。unsigned int biSizeImage; // 像素数据所占大小, 这个值应该等于上面文件头结构中bfSize-bfOffBitsint biXPelsPerMeter; // 说明水平分辨率,用象素/米表示。一般为0int biYPelsPerMeter; // 说明垂直分辨率,用象素/米表示。一般为0unsigned int biClrUsed; // 说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)。unsigned int biClrImportant;// 说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。
} BitMapInfoHeader;
rgb
// 24bit
typedef struct {unsigned char rgblue;unsigned char rgbgreen; unsigned char rgbred;unsigned char rgbreserved;
} PixelInfo;
代码demo
读取bmp文件数据头
#ifndef _BMP_H_
#define _BMP_H_#pragma pack(1)typedef struct {unsigned short bfType; // "BM"unsigned int bfSize; // 文件大小unsigned short bfReserved1; // 保留,必须设置为0unsigned short bfReserved2; // 保留,必须设置为0unsigned int bfOffBits; // 从文件头到像素数据的偏移
} BitMapFileHeader;typedef struct{unsigned int biSize; // 此结构体的大小int biWidth; // 图像的宽int biHeight; // 图像的高unsigned short biPlanes; // 表示bmp图片的平面属,显然显示器只有一个平面,所以恒等于1unsigned short biBitCount; // 一像素所占的位数,一般为24unsigned int biCompression; // 说明图象数据压缩的类型,0为不压缩。unsigned int biSizeImage; // 像素数据所占大小, 这个值应该等于上面文件头结构中bfSize-bfOffBitsint biXPelsPerMeter; // 说明水平分辨率,用象素/米表示。一般为0int biYPelsPerMeter; // 说明垂直分辨率,用象素/米表示。一般为0unsigned int biClrUsed; // 说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)。unsigned int biClrImportant;// 说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。
} BitMapInfoHeader;// 24bit
typedef struct {unsigned char rgblue;unsigned char rgbgreen; unsigned char rgbred;unsigned char rgbreserved;
} PixelInfo;#endif
#include <stdio.h>
#include "bmp.h"void show_bmp_file_head(BitMapFileHeader *data)
{printf("#########################################\n");printf("bfType %x\n", data->bfType);printf("bfSize %d\n", data->bfSize/1024);printf("bfOffBits %d\n", data->bfOffBits);
}void show_bmp_info_head(BitMapInfoHeader *data)
{printf("#########################################\n");printf("biSize %d\n", data->biSize);printf("biWidth %d\n", data->biWidth);printf("biHeight %d\n", data->biHeight);printf("biPlanes %d\n", data->biPlanes);printf("biBitCount %d\n", data->biBitCount);printf("biCompression %d\n", data->biCompression);printf("biXPelsPerMeter %d\n", data->biXPelsPerMeter);printf("biYPelsPerMeter %d\n", data->biYPelsPerMeter);printf("biClrUsed %d\n", data->biClrUsed);printf("biClrImportant %d\n", data->biClrImportant);
}void show_bmp_rgb(PixelInfo *data)
{printf("#########################################\n");printf("rgblue %2x\n", data->rgblue);printf("rgbgreen %2x\n", data->rgbgreen);printf("rgbred %2x\n", data->rgbred);
}int main(int argc, char *argv[])
{FILE *fp = NULL;BitMapFileHeader FileHead;BitMapInfoHeader InfoHead;PixelInfo rgbinfo;char *ptr = NULL;int i, j;fp = fopen(argv[1], "rb");if(fp == NULL){perror("open bmp file error");return -1;}fread(&FileHead, sizeof(BitMapFileHeader), 1, fp);fread(&InfoHead, sizeof(BitMapInfoHeader), 1, fp);show_bmp_file_head(&FileHead);show_bmp_info_head(&InfoHead);show_bmp_rgb(&rgbinfo);ptr = (unsigned char *)malloc(FileHead.bfSize);if(ptr == NULL){perror("malloc ptr fail\n");return 0;}for(i = 0; i <= InfoHead.biHeight; i++){for(j = 0; j <= InfoHead.biWidth; j++){fread(&rgbinfo, sizeof(PixelInfo), 1, fp);*ptr = 0xff << 24 | rgbinfo.rgbred << 16 | rgbinfo.rgbgreen << 8 | rgbinfo.rgblue;memset(&rgbinfo, 0, sizeof(PixelInfo));ptr++;if((rgbinfo.rgbred == 255) && (rgbinfo.rgbgreen == 255) && (rgbinfo.rgblue == 255))printf(" ");elseprintf("#");}printf("\n");} fclose(fp);return 0;
}
lin@u-android:~/lin/workspace/demo_project/bmp$ gcc -o bmp_test show_bmp_head.c
lin@u-android:~/lin/workspace/demo_project/bmp$ ./bmp_test ./test.bmp
#########################################
bfType 4d42
bfSize 459
bfOffBits 54
#########################################
biSize 40
biWidth 507
biHeight 309
biPlanes 1
biBitCount 24
biCompression 0
biXPelsPerMeter 0
biYPelsPerMeter 0
biClrUsed 0
biClrImportant 0
相关文章:

Bmp图片格式介绍
Bmp图片格式介绍 介绍 BMP是英文Bitmap(位图)的简写,它是Windows操作系统中的标准图像文件格式,能够被多种Windows应用程序所支持。随着Windows操作系统的流行与丰富的Windows应用程序的开发,BMP位图格式理所当然地被…...

Day4 leetcode
Day4 啊啊啊啊,什么玩意,第一次因为测评没过,约好的面试取消了,好尴尬呀,还有一家厦门的C/C电话面,是一家我还挺喜欢的公司,面的稀烂,只能安慰自己我现在手上至少有一个offer 有效括…...

Java设计模式-原型模式
1、定义 原型模式是一种创建型模式,用于创建重复的对象,并且保证性能。原型模式创建的对象是由原型对象自身创建的,是原型对象的一个克隆,和原型对象具有相同的结构和相同的值。 2、适用场景 创建对象时我们不仅仅需要创建一个新…...

2023年度最新且最详细Ubuntu的安装教程
目录 准备ISO镜像 1.去官网下载镜像,或者找有镜像源的网站下载 阿里云镜像站 2. 如果服务器是打算直接把底层系统安装为Ubuntu的话还需制作系统U盘 安装 1.新建虚拟机调整基础配置 2.打开电源,进入安装界面(到这一步就跟u盘安装步骤一致…...

unix高级编程-fork之后父子进程共享文件
~/.bash_profile:每个用户都可使用该文件输入专用于自己使用的shell信息,当用户登录时,该文件仅仅执行一次!默认情况下,他设置一些环境变量,执行用户的.bashrc文件. 这里我看到的是centos的操作,但我用的是debian系的ubuntu,百度了一下发现debian的在这里…...

vue+echarts:柱状图横向展示和竖向展示
第021个点击查看专栏目录本示例是显示柱状图,分别是横向展示和纵向展示。关键是X轴和Y轴的参数互换。 文章目录横向示例效果横向示例源代码(共81行)纵向示例效果纵向示例源代码(共81行)相关资料参考专栏介绍横向示例效…...

SealOS 一键安装 K8S
环境 # 查看系统发行版 $ cat /etc/os-release NAME"CentOS Linux" VERSION"7 (Core)" ID"centos" ID_LIKE"rhel fedora" VERSION_ID"7" PRETTY_NAME"CentOS Linux 7 (Core)" ANSI_COLOR"0;31" CPE_NA…...

python网络编程详解
最近在看《UNIX网络编程 卷1》和《FREEBSD操作系统设计与实现》这两本书,我重点关注了TCP协议相关的内容,结合自己后台开发的经验,写下这篇文章,一方面是为了帮助有需要的人,更重要的是方便自己整理思路,加…...

ICRA 2023 | 首个联合暗光增强和深度估计的自监督方法STEPS
原文链接:https://www.techbeat.net/article-info?id4629 作者:郑宇鹏 本文中,我们提出了STEPS,第一个自监督框架来联合学习图像增强和夜间深度估计的方法。它可以同时训练图像增强网络和深度估计网络,并利用了图像增…...

基于react+nodejs+mysql开发用户中心,用于项管理加入的项目的用户认证
基于reactnodejsmysql开发用户中心,用于项管理加入的项目的用户认证用户中心功能介绍页面截图后端采用架构user表projects表project_user表仓库地址用户中心功能介绍 用户中心项目,用于统一管理用户信息、登录、注册、鉴权等 功能如下: 用…...

mapreduce与yarn
文章目录一、MapReduce1.1、MapReduce思想1.2、MapReduce实例进程1.3、MapReduce阶段组成1.4、MapReduce数据类型1.5、MapReduce关键类1.6、MapReduce执行流程1.6.1、Map阶段执行流程1.6.2、Map的shuffle阶段执行流程1.6.3、Reduce阶段执行流程1.7、MapReduce实例WordCount二、…...

鲲鹏云服务器上使用 traceroute 命令跟踪路由
traceroute 命令跟踪路由 它由遍布全球的几万局域网和数百万台计算机组成,并通过用于异构网络的TCP/IP协议进行网间通信。互联网中,信息的传送是通过网中许多段的传输介质和设备(路由器,交换机,服务器,网关…...

代码随想录算法训练营第47天 || 198.打家劫舍 || 213.打家劫舍II || 337.打家劫舍III
代码随想录算法训练营第47天 || 198.打家劫舍 || 213.打家劫舍II || 337.打家劫舍III 198.打家劫舍 题目介绍 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&…...

JVM调优方式
对JVM内存的系统级的调优主要的目的是减少GC的频率和Full GC的次数。 1.Full GC 会对整个堆进行整理,包括Young、Tenured和Perm。Full GC因为需要对整个堆进行回收,所以比较慢,因此应该尽可能减少Full GC的次数。 2.导致Full GC的原因 1)年老…...

机器学习模型监控的 9 个技巧
机器学习 (ML) 模型是非常敏感的软件;它们的成功使用需要进行仔细监控以确保它们可以正常工作。当使用所述模型的输出自动做出业务决策时尤其如此。这意味着有缺陷的模型通常会对终端客户的体验产生真正的影响。因此,监控输入数据(和输出&…...

Linux 实现鼠标侧边键实现代码与网页的前进、后退
前言 之前一直是使用windows进行开发,最近转到linux后使用VsCode编写代码。 但是不像在win环境下,使用鼠标侧边键可以实现代码的前向、后向跳转。浏览网页时也不行(使用Alt Left可以后退)。 修改键盘映射实在没有那么方便&…...

健身蓝牙耳机推荐,推荐五款适合健身的蓝牙耳机
出门运动健身,有音乐的陪伴是我们坚持运动的不懈动力,在健身当中佩戴的耳机,佩戴舒适度以及牢固程度是我们十分需要注意的,还不知道如何选择健身蓝牙耳机,可以看看下面这些运动蓝牙耳机分享。 1、南卡Runner Pro4骨传…...

Type-c诱骗取电芯片大全
随着Type-C的普及和推广,目前市面上的电子设备正在慢慢淘汰micro-USB接口,逐渐都更新成了Type-C接口,micro-USB接口从2007年上市,已经陪伴我们走过十多个年头,如今也慢慢退出舞台。 今天我们评测的产品是市面上Type-C…...

Scala模式匹配详解(第八章:基本语法、模式守卫、模式匹配类型)(尚硅谷笔记)
模式匹配第 8 章 模式匹配8.1 基本语法8.2 模式守卫8.3 模式匹配类型8.3.1 匹配常量8.3.2 匹配类型8.3.3 匹配数组8.3.4 匹配列表8.3.5 匹配元组8.3.6 匹配对象及样例类8.4 变量声明中的模式匹配8.5 for 表达式中的模式匹配8.6 偏函数中的模式匹配(了解)第 8 章 模式匹配 Scal…...

Linux:基于libevent读写管道代码
基于libevent读写管道代码: 读端: #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> #include <event2/event.h> #include…...

2022年中职网络安全逆向题目整理合集
中职网络安全逆向题目整理合集逆向分析:PE01.exe算法破解:flag0072算法破解:flag0073算法破解:CrackMe.exe远程代码执行渗透测试天津逆向re1 re2逆向分析:PE01.exe FTPServer20220509(关闭链接) FTP用户名:PE01密码…...

Tencent OS下逻辑卷(LVM)增加硬盘扩容
上一篇文章写了逻辑卷创建以及使用剩余空间为已经创建的逻辑卷扩容。 本篇是针对卷组空间已经用尽时的扩容方法。那就是增加硬盘。 首先我们为虚拟机增加硬盘/dev/sdd 使用fdisk为/dev/sdd分区,方法在上一篇文章已经描述,在此不再赘述。 新增的硬盘使用如下命令添加到卷组…...

【Java】Spring的创建和使用
Spring的创建和使用 Spring就是一个包含众多工具方法的IOC容器。既然是容器,那么就具备两个最主要的功能: 将对象存储到容器中从容器中将对象取出来 在Java语言当中对象也叫作Bean。 1. 创建Spring项目 创建一个普通maven项目添加Spring框架支持(spri…...

【HTML】HTML 表单 ④ ( textarea 文本域控件 | select 下拉列表控件 )
文章目录一、textarea 文本域控件二、select 下拉列表控件一、textarea 文本域控件 textarea 文本域 控件 是 多行文本输入框 , 标签语法格式如下 : <textarea cols"每行文字字符数" rows"文本行数">多行文本内容 </textarea>实际开发中 并不…...

MySQL 操作 JSON 数据类型
MySQL 从 v5.7.8 开始支持 JSON 数据类型。 JSON 数据类型和传统数据类型的操作还是有很大的差别,需要单独学习掌握。好在 JSON 数据类型的学习成本不算太高,只是在 SQL 语句中扩展了 JSON 函数,操作 JSON 数据类型主要是对函数的学习。 新…...

关于vue3生命周期的使用、了解以及用途(详细版)
生命周期目录前言组合式写法没有 beforeCreate / created 生命周期,并且组合式写生命周期用哪个先引哪个beforeCreatecreatedbeforeMount/onBeforeMountmounted/onMountedbeforeUpdate/onBeforeUpdateupdated/onUpdatedbeforeUnmount/onBeforeUnmountunmounted/onUn…...

2月,真的不要跳槽。
新年已经过去,马上就到金三银四跳槽季了,一些不满现状,被外界的“高薪”“好福利”吸引的人,一般就在这时候毅然决然地跳槽了。 在此展示一套学习笔记 / 面试手册,年后跳槽的朋友可以好好刷一刷,还是挺有必…...

Vulnhub靶场----4、DC-4
文章目录一、环境搭建二、渗透流程三、思路总结一、环境搭建 DC-4下载地址:https://download.vulnhub.com/dc/DC-4.zip kali:192.168.144.148 DC-4:192.168.144.152 二、渗透流程 端口扫描:nmap -T5 -p- -sV -sT -A 192.168.144.1…...

51单片机学习笔记_12 LCD1602 原理及其模块化代码
LCD1602 liquid crystal display 液晶显示屏,一种字符型液晶显示模块,可以显示 16*2 个字符,每个字符是 5*7 点阵。 P0 P2 会和数码管、LED 一定程度上冲突。 地。 Vcc。 调对比度的。 RS:数据指令端。1代表 DB 是数据&#x…...

科技 “新贵”ChatGPT 缘何 “昙花一现” ,仅低代码风靡至今
恍惚之间,ChatGPT红遍全网,元宇宙沉入深海…… 在科技圈,见证了太多“昙花一现”,“新贵” ChatGPT 的爆火几乎复制了元宇宙的路径,它会步元宇宙的后尘,成为下一个沉入深海的工具吗? 不可否认的…...