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…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)
在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马(服务器方面的)的原理,连接,以及各种木马及连接工具的分享 文件木马:https://w…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...
elementUI点击浏览table所选行数据查看文档
项目场景: table按照要求特定的数据变成按钮可以点击 解决方案: <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...
