Bitmap位图
介绍
位图(Bitmap),又称栅格图或点阵图,是使用像素阵列来表示的图像。根据位深度,可将位图分为1、4、8、16、24及32位图像等。每个像素使用的信息位数越多,可用的颜色就越多,颜色表现就越逼真,相应的数据量越大。
BMP文件是微软公司所开发的一种交换和存储数据的方法。BMP格式的缺点是,要占用较大的存储空间,文件尺寸太大。
BMP文件结构
BMP文件存储结构的格式可以在Windows中的WINGDI.h文件中找到定义。
BMP文件总体上由4部分组成,分别是位图文件头、位图信息头、调色板和图像数据。
| 位图文件头 |
| 位图信息头 |
| 彩色表/调色板 |
| 位图数据 |
解析
BITMAPFILEHEADER文件头
用于描述 Windows 位图(Bitmap)文件的文件头信息,包含了图像类型、图像大小、图像数据存放地址和两个保留未使用的字段,其定义如下
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;bfType:这是一个 16 位无符号整数,用于标识文件类型。对于位图文件,这个值通常是0x4D42,其对应的 ASCII 码是BM。通过检查这个值,程序可以快速判断一个文件是否可能是位图文件
bfSize:这是一个 32 位无符号整数,表示位图文件的大小,单位是字节。这个值包含了文件头、信息头、颜色表(如果有)和像素数据的全部大小。例如,如果一个位图文件的bfSize值为1024字节,那么从文件开始到结束总共的数据量是 1024 字节。
bfOffBits:这是一个 32 位无符号整数,表示从文件头的起始位置到实际像素数据的偏移量,单位是字节。这个偏移量包括了文件头和信息头(以及可能存在的颜色表)的大小。
BITMAPINFOHEADER位图信息头
BITMAPINFOHEADER是 Windows 图形编程中用于描述位图(Bitmap)详细信息的一个关键结构体。它紧跟在BITMAPINFOHEADER之后,为程序提供了足够的信息来理解和处理位图的像素数据。
typedef struct tagBITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, FAR *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;| 字段名 | 大小(单位:字节) | 描述 |
| biSize | 4 | 本结构的大小,在windows中,此字段的值总为28h字节=40字节 |
| biWidth | 4 | BMP图像的宽度,单位像素 |
| biHeight | 4 | |
| biPlanes | 2 | 总为0 |
| biBitCount | 2 | BMP图像的色深,即一个像素用多少位表示,常见的有1、4、8、16、24和32,分别对应单色、16色、256色、16位高彩色、24位真彩色和32位增强型真彩色 |
| biCompression | 4 | 压缩方式,0表示不压缩,1表示RLE8压缩,2表示RLE4压缩,3表示每个像素值由指定的掩码决定 |
| biSizeImage | 4 | BMP图像数据大小,必须是4的倍数,图像数据大小不是4的倍数时用0填充补足 |
| biXPelsPerMeter | 4 | 水平分辨率,单位像素/m |
| biYPelsPerMeter | 4 | 垂直分辨率,单位像素/m |
| biClrUsed | 4 | BMP图像使用的颜色,0表示使用全部颜色,对于256色位图来说,此值为100h=256 |
| biClrImportant | 4 | 重要的颜色数,此值为0时所有颜色都重要,对于使用调色板的BMP图像来说,当显卡不能够显示所有颜色时,此值将辅助驱动程序显示颜色 |
彩色表/调色板(color table)
彩色表/调色板是是单色、16色和256色图像文件所特有的,相对应的调色板大小是2、16和256,调色板以4字节为单位,每4个字节存放一个颜色值,图像的数据是指向调色板的索引。
可以将调色板想象成一个数组,每个数组元素的大小为4字节,调色板的数据结构定义:
typedef struct tagRGBQUAD {
BYTE rgbBlue;
BYTE rgbGreen;
BYTE rgbRed;
BYTE rgbReserved;
} RGBQUAD;WebP
定义
WebP是由Google开发的一种现代图像格式,旨在提供更小的文件大小,同时保持较高的图像质量。它支持有损压缩和无损压缩,还支持透明背景(类似PNG)和动画(类似GIF)。
特点
压缩效率高
有损压缩比JPG文件小约25%~34%
无损压缩比PNG文件小约26%
支持透明背景(Alpha通道):无损和有损压缩都支持透明
支持动画:可以替代GIF格式
支持渐进加载(Progressive Decoding):提供更快的加载体验。
广泛支持:现代浏览器(如Chrome、Edge、Firefox、Safari等)都支持WebP
优点
高效压缩:相较JPG和PNG文件体积更小,节省带宽
多功能性:同时支持透明(类似PNG)、动画(类似GIF)和高质量压缩(类似JPG)。
提示网站性能:减少图像大小,提升页面加载速度。
下载链接
https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.4.0-windows-x64.zip
参考资料
https://developers.google.cn/speed/webp?hl=zh-cn
格式解析
RIFF文件格式
WebP文件格式基于RIFF(资源交换文件格式)文档格式
RIFF文件的基本元素是数据块。它由以下部分组成:
+++++++++++++++++++++
Chunk FourCC
+++++++++++++++++++++
Chunk Size
+++++++++++++++++++++
Chunk Payload
+++++++++++++++++++++
Chunk FourCC:32位
用于标识分块的四位ASCII代码
分块大小:32位
分块的大小,不包括此字段、区块标识符或填充
分块载荷:分块大小(字节)
数据载荷。如果Chunk Size(数据块大小)为奇数,则会添加一个填充字节(必须为0,以符合RIFF规范)。
注意:RIFF有一个惯例,即全大写的块FourCC是适用于任何RIFF文件格式的标准块,而特定于文件格式的FourCC全部采用小写形式。WebP不遵循此惯例。
WebP文件头
RIFF文件大小WEBP,统称为WebP文件头:WebP header,4个字节(RIFF),4个字节的文件大小,4个字节的标识(WEBP),总计12个字节。
https://developers.google.cn/speed/webp/docs/riff_container?hl=zh-cn
“RIFF”:32位
ASCII字符“R"”I"“F"”F"
文件大小:32位(uint32)
文件的大小(以字节为单位),从偏移量8开始。此字段的最大值为2^32减10字节,因此整个文件的大小不得超过4GiB减2字节。
“WEBP”:32位
ASCII字符“W"”E“”B""P"
WebP文件必须以包含FourCC"WEBP"的RIFF标头开头。标头中的文件大小是后续数据块的总大小加上“WEBP”FourCC的4字节。文件不应该在文件大小指定的数据后面包含任何数据。读取器可以解析此类文件,并忽略尾随数据。由于任何分块的大小都是偶数,因此RIFF标头给出的大小也是偶数。
JPEG
JPEG(Joint Photographic Experts Group)是同名专家小组开发的图像压缩技术标准,该标准由国际标准化组织(ISO)制订,是面向连续色调静止图像的一种压缩标准。JPEG格式是最常用的图像文件格式,后缀名为.jpg或.jpeg。其主要是采用预测编码(DPCM)、离散余弦变换(DCT)以及熵编码的联合编码方式,以去除冗余的图像和彩色数据,属于有损压缩格式,它能够将图像压缩在很小的存储空间,一定程度上会造成图像数据的损伤。
二进制文件
格式解析
JPEG文件头2字节 FF D8
FF D8标识JPEG文件头
APP0图像识别信息 FF E0
| 名称 | 字节数 | 值 | 说明 |
| 段标识 | 1 | FF | |
| 段类型 | 1 | E0 | |
| 段长度 | 2 | 0010 | 如果有缩略图=16+3n |
| 以下为段内容 | |||
| 交换格式 | 5 | 4A46494600 | JFIF的ASCII码 |
| 主版本号 | 1 | ||
| 次版本号 | 1 | ||
| 密度单位 | 1 | 0=无单位;1=点数/英寸;2=点数/厘米 | |
| X像素密度 | 2 | 水平方向的密度 | |
| Y像素密码 | 2 | 垂直方向的密度 | |
| 缩略图X像素 | 1 | 缩略图水平像素数目 | |
| 缩略图Y像素 | 1 | 缩略图垂直像素数目 | |
| 如果“缩略图X像素”和“缩略图Y像素”的值均>0,才有以下的数据 | |||
| RGB缩略图 | 3xN | n=缩略图像素总数=缩略图X像素x缩略图Y像素 |
DQT定义量化表 FF DB
| 名称 | 字节数 | 值 | 说明 |
| 段标识 | 1 | FF | |
| 段类型 | 1 | DB | |
| 段长度 | 2 | 43 | 其值=3+n(当只有一个QT时) |
| 以下为段内容 | |||
| QT信息 | 1 | 0-3位 | QT号 |
| 4-7位 | QT精度(0=8bit,1字节;否则=16bit,2字节) | ||
| QT | n | n=64xQT精度的字节数 |
SOF0图像基本信息(帧图像起始块)FF C0
| 名称 | 字节数 | 值 | 说明 |
| 段标识 | 1 | FF | |
| 段类型 | 1 | C0 | |
| 段长度 | 2 | 其值=8+组件数量x3 | |
| 以下为段内容 | |||
| 样本精度 | 1 | 8 | 每个样本位数(大多数软件不支持12和16) |
| 图片高度 | 2 | ||
| 图片宽度 | 2 | ||
| 组件数量 | 1 | 3 | 1=灰度图,3=YCbCr/YIQ彩色图,4=CMYK彩色图 |
| 组件ID | 1 | 1=Y,2=Cb,3=Cr,4=I,5=Q | |
| 采样系数 | 1 | 0-3位:垂直采样系数 4-7位:水平采样系数 | |
| 量化表号 | 1 |
DHT定义huffman表 FF C4
| 名称 | 字节数 | 值 | 说明 |
| 段标识 | 1 | FF | |
| 段类型 | 1 | C4 | |
| 段长度 | 2 | 其值=19+n(当只有一个HT表时) | |
| HT信息 | 1 | 0-3位:HT号 4位:HT类型,0=DC表,1=AC表 5-7位:必须=0 | |
| HT位表 | 16 | 这16个数的和应该<=256 | |
| HT值表 | n | n=表头16个数的和 |
SOS扫描行开始 FF DA
| 名称 | 字节数 | 值 | 说明 |
| 段标识 | 1 | FF | |
| 段类型 | 1 | DA | |
| 段长度 | 2 | 000C | 其值=6+2x扫描行内组件数量 |
| 扫描行内组件数量 | 1 | 3 | 必须>=1,<=4否则错误,通常=3 |
| 组件ID | 1 | 1=Y,2=Cb,3=Cr,4=I,5=Q | |
| Huffman表号 | 1 | 0-3位:AC表号(其值=0...3) 4-7位:DC表号(其值=0...3) | |
| 剩余3个字节 | 3 | 忽略 |
EOI文件尾 FF D9
| 名称 | 字节数 | 值 |
| 段标识 | 1 | FF |
| 段类型 | 1 | D9 |
PNG
PNG介绍
png是图像文件存储格式,其目的是试图替代GIF和TIFF文件格式,同时增加一些GIF文件格式所不具备的特性。流式网络图形格式(Portable Network Graphic Format,PNG)名称来源于非官方的“PNG‘s Not GIF",是一种位图文件存储格式。PNG用来存储灰度图像时,灰度图像的深度可多到16位,存储彩色图像时,彩色图像的深度可多到48位,并且还可存储多到16位的α通道数据。PNG使用从LZ77派生的无损数据压缩算法。
PNG文件结构
PNG图像格式文件由一个8字节的PNG文件署名域和按照特定结构组织的3个以上的数据块(chunk)组成。
PNG定义了两种类型的数据块,一种是称为关键数据块(critical chunk),这是标准的数据块,另一种叫做辅助数据块(ancillary chunks),这是可选的数据块。关键数据块定义了4个标准数据块,每个PNG文件都必须包含它们,PNG读写软件也都必须要支持这些数据块。
PNG文件署名域
在PNG文件前8字节的PNG文件署名域用来识别该文件是不是PNG文件。该域的值是:
89 50 4e 47 0d 0a 1a 0a
PNG数据块
PNG文件中的每个数据块都由表1所示的4个域组成。
| 名称 | 字节数 | 说明 |
| Length(长度) | 4字节 | 指定数据块中数据域的长度 |
| Chunk Type Code(数据块类型码) | 4字节 | 数据块类型码由ASCII字母(A-Z和a-z)组成 |
| Chunk Data(数据块数据) | 可变长度 | 存储按照Chunk Type Code指定的数据 |
| CRC(循环冗余检测) | 4字节 | 存储用来检测是否有错误的循环冗余码 |
PNG文件中的关键数据块的4个标准数据块分别是文件数据块、调色板数据块、图像数据块、图像结束数据块。
| 数据块符号 | 数据块名称 | 多数据块 | 可选 | 位置限制 |
| IHDR | 文件头数据块 | 否 | 否 | 第一块 |
| cHRM | 基色和白色点数据块 | 否 | 是 | 在PLTE和IDAT之前 |
| gAMA | 图像Y数据块 | 否 | 是 | 在PLTE和IDAT之前 |
| sBIT | 样本有效位数据块 | 否 | 是 | 在PLTE和IDAT之前 |
| PLTE | 调色板数据块 | 否 | 是 | 在IDAT之前 |
| bKGD | 背景颜色数据块 | 否 | 是 | 在PLTE之后IDAT之前 |
| hIST | 图像直方图数据块 | 否 | 是 | 在PLTE之后IDAT之前 |
| tRNS | 图像透明数据块 | 否 | 是 | 在PLTE之后IDAT之前 |
| oFFs | 专用公共数据块 | 否 | 是 | 在IDAT之前 |
| pHYs | 物理像素尺寸数据块 | 否 | 是 | 在IDAT之前 |
| sCAL | 专用公共数据块 | 否 | 是 | 在IDAT之前 |
| IDAT | 图像数据块 | 是 | 否 | 与其他IDAT连续 |
| tIME | 图像最后修改时间数据块 | 否 | 是 | 无限制 |
| tEXt | 文本信息数据块 | 是 | 是 | 无限制 |
| zTXt | 压缩文本数据块 | 是 | 是 | 无限制 |
| fRAc | 专用公共数据块 | 是 | 是 | 无限制 |
| glFg | 专用公共数据块 | 是 | 是 | 无限制 |
| glFt | 专用公共数据块 | 是 | 是 | 无限制 |
| glFx | 专用公共数据块 | 是 | 是 | 无限制 |
| IEND | 图像结束数据 | 否 | 否 | 最后一个数据块 |
文件头数据块
文件头数据块的数据块类型码为IHDR,它包含有PNG文件中存储的图像数据的基本信息,并作为第一个数据块出现在PNG数据流中,而且一个PNG数据流中只能有一个文件头数据块。文件头数据块由13个字节组成,格式如下:
| 域的名称 | 字节数 | 说明 |
| Width | 4 | 图像宽度,以像素为单位 |
| Height | 4 | 图像高度,以像素为单位 |
| Bit depth | 1 | 图像深度: 索引彩色图像:1,2,4或8 灰度图像:1,2,4,8或16 真彩色图像:8或16 |
| ColorType | 1 | 颜色类型: 0:灰度图像 2:真彩色图像 3:索引彩色图像 4:带α通道数据的灰度图像 6:带α通道数据的真彩色图像 |
| Compression method | 1 | 压缩方法(LZ77派生算法) |
| Filter method | 1 | 滤波器方法 |
| Interlace method | 1 | 隔行扫描方法: 0:非隔行扫描 1:Adam7 |
GIF
介绍
GIF的全称是Graphics Interchange Format,可译为图形交换格式,用于以超文本标志语言方式显示索引彩色图像。
文件格式
文件头是一个带有识别GIF格式数据流的数据块,用以区分早期版本和新版本
逻辑屏幕描述区定义了与图像数据相关的图像平面尺寸、彩色深度,并指明后面的调色板数据区属于全局调色板还是局部调色板。若使用的是全局调色板,则生成一个24bit的RGB全局调色板,其中一个基色占用一个字节。
调色板数据区。分通用调色板和局部调色板。其中通用调色板适用于文件中所有图像,局部调色板只适用于某一个图像。
图像数据区的内容有两类,一类是纯粹的图像数据,一类是用于特殊目的的数据块(包含专用应用程序代码和不可打印的注释信息)。在GIF89a格式的图像文件中,如果一个文件中包含多个图像,图像数据区将依次重复数据块序列。
结束标志区的作用主要是标记整个数据流的结束。
Header
在文件头中总包含着magic number数据,标识当前的文件类型,对于gif而言,它的前三个字节总是 0x47,0x49,0x46,而后三个字节标识当前gif的版本,可能是87a也可能是89a,这是header中包含的全部信息。
LogicScreenDescriptor
紧随Header之后的是LogicScreenDescriptor,这里包含了整个gif文件的全局信息,固定7个字节。
| 名称 | 字节个数 | 说明 |
| 宽 | 2 | 小端形式存储 |
| 高 | 2 | 同上 |
| 压缩字节 | 1 | 1位:全局颜色标识,如果存在则全局颜色表紧跟在LogicScreenDescriptor后面出现。 2-4位:色表中每个颜色通道的位深,111即表示每个颜色通道允许的最大值为255,也就是7+1位所能表示的最大值。 5位:排序标识,标识色表中的颜色是否经过排序,排序按颜色出现的次数从高至低,也就是说越重要的颜色排在更前面。 6-8位:全局色表的个数,记为n,则颜色个数为2(n+1) |
| 索引 | 1 | 背景色在全局表中的索引,全局色表存在时有效,当图像不能完全占满gif的实际大小时,应显示背景色 |
| 宽高比 | 1 | 一般不设置 |
Global Color Table
全局颜色表,只有当全局颜色标识为1时才存在;gif中颜色以rgb格式排序,也就是说每个颜色三字节,128个颜色则占用384字节。
Extension
在gif中还存在着很多扩展块,这些块的格式都是固定的。
[0x21][flag][info]?[subdata]?[0x00]
固定值[0x21]标识这是一个扩展块
[flag]标识当前扩展块的类型
[info]是可选的,携带了所需的额外信息,它的第一个字节表示后续有多少个字节的数据
[subdata]同样是可选的,这是携带的实际数据,它的第一个字节表示后续有多少个字节的数据,如果跳过这些字节后遇到的字节值不是0x00,那么这个字节表示的依然是后续的数据子块大小
固定值[0x00]标识块结束
Comment Extension
评论扩展,存储额外的文字数据。这些数据不能被感知,也就是与图像渲染无关,大部分解析器会跳过它。该扩展块以0x21,0xfe开始,其后跟数据子块(subdata);GIF只支持ASCII表中的字符,也就是一字节表示一字符,如果遇到不能打印的ASCII字符时,gif规范建议用空格(0x20)代替。
该扩展块建议始终在文件头或文件尾,不打扰到更重要的数据(图像或文本)的解析。
Graphic Control Extension
图形控制扩展,顾名思义包含了可以控制图形展示的信息,它的作用范围是此块出现后的第一个Image或Plain Text Extension,固定7字节,其中0x21,0xf9占用两个字节。
Image Descriptor
图像描述符,描述了当前图像的信息。遇到此块时则表示着一个Image的开始,固定10个字节,其中第一个字节始终是0x2c。
Local Color Table
本地色表,同全局色表,在本地色表标识为1时存在,如果不存在则使用全局色表。如果想要gif重现真彩色,可以利用本地色表的特性,将一个完整的图片切割的足够小,并对它们应用不同的色表,但这在大部分时候没有必要,因为这会增加整个gif的体积。
Image Data
图像数据紧跟在本地色表(不存在则跟随Image Descriptor)后,实际是经过压缩后的颜色索引。在gif编码中将图像中出现的所有颜色经过算法压缩至256色内,然后将每个颜色替换为在色表中最接近的颜色的索引,最后通过lzw算法将这些索引字节压缩。
Plain Text Extension
纯文本扩展,存放ASCII文本数据,这些文本需要被渲染到gif中,虽然大部分解析器都忽略它。此块包含15字节的固定信息,其后是可变长度的数据子块,用于存放文本数据。
Trailer
文件结尾,包含固定值0x3b
示例
获取图片宽高