PNG、JPEG、BMP等几种图片格式详解(一)—— PNG

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PNG、JPEG、BMP等几种图片格式详解(一)—— PNG相关的知识,希望对你有一定的参考价值。

参考技术A

图片有很多的格式,包括 PNG 、 JPEG 、 JPG 、 BMP 等,下面我们就详细的说一下这几张图片的格式,并进行详细的对比。

便携式网络图形 (Portable Network Graphics) 是一种无损压缩的位图图形格式 。其设计目的是试图替代 GIF 和 TIFF 文件格式,同时增加一些GIF文件格式所不具备的特性。PNG的名称来源于“可移植网络图形格式 (Portable Network Graphic Format,PNG) ”,也有一个非官方解释 “PNG\'s Not GIF” 。PNG使用从 LZ77 派生的无损数据压缩算法,一般应用于JAVA程序、网页或S60程序中,原因是它压缩比高,生成文件体积小。

PNG格式的图片具有如下特点:

PNG图像格式文件(或者称为数据流)由一个8字节的PNG文件署名 (PNG file signature) 域和按照特定结构组织的3个以上的数据块 (chunk) 组成。

文件署名域

8字节的PNG文件署名域用来识别该文件是不是PNG文件。该域的值是:

数据块类型码命名约定

PNG定义了两种类型的数据块,一种是称为关键数据块 (critical chunk) ,这是必需的数据块,另一种叫做辅助数据块 (ancillary chunks) ,这是可选的数据块。关键数据块定义了4个标准数据块,每个PNG文件都必须包含它们,PNG读写软件也都必须要支持这些数据块。虽然PNG文件规范没有要求PNG编译码器对可选数据块进行编码和译码,但规范提倡支持可选数据块。

数据块的4个域组成如下图所示。

下面我们就分析下这个结构。

关键数据块

关键数据块的组成如下所示。

辅助数据块

看下面这个数据结构图。

PNG格式有8位、24位、32位三种形式,其中8位PNG支持两种不同的透明形式(索引透明和alpha透明),24位PNG不支持透明,32位PNG在24位基础上增加了8位透明通道,因此可展现256级透明程度。
PNG8和PNG24后面的数字则是代表这种PNG格式最多可以索引和存储的颜色值。”8″代表2的8次方也就是256色,而24则代表2的24次方大概有1600多万色。

具体如下图所示。

1. PNG,JPEG,BMP,JIF图片格式详解及其对比
2. PNG

PNG,JPEG,BMP,JIF图片格式详解及其对比

图片格式详解
不知道大家有没有注意过网页里,手机里,平板里的图片,事实上,图片格式多样,不同平台对不同格式的图片支持也不一样,所以需要根据不同场合,使用不同格式的图片。
一.PNG格式
便携式网络图形(Portable Network Graphics,PNG)是一种无损压缩的位图图形格式,支持索引、灰度、RGB三种颜色方案以及Alpha通道等特性。

PNG格式有8位、24位、32位三种形式,其中8位PNG支持两种不同的透明形式(索引透明和alpha透明),24位PNG不支持透明,32位PNG在24位基础上增加了8位透明通道,因此可展现256级透明程度。

PNG8和PNG24后面的数字则是代表这种PNG格式最多可以索引和存储的颜色值。”8″代表2的8次方也就是256色,而24则代表2的24次方大概有1600多万色。

格式最高支持色彩通道索引色编辑支持透明支持
PNG8256索引色支持支持设定特定索引色为透明色(布尔透明)
支持为索引色附加8位透明度(256阶alpha透明)
PNG24约1600万色不支持不支持
PNG32约1600万色不支持支持8位透明度(256阶alpha透明)

1.PNG的文件结构

对于一个PNG文件来说,其文件头总是由位固定的字节来描述的:

进制编码
十六进制数89 50 4E 47 0D 0A 1A 0A

其中第一个字节0x89超出了ASCII字符的范围,这是为了避免某些软件将PNG文件当做文本文件来处理。文件中剩余的部分由3个以上的PNG的数据块(Chunk)按照特定的顺序组成,因此,一个标准的PNG文件结构应该如下:

PNG文件标志 | PNG数据块 …… | PNG数据块

2.PNG数据块(Chunk)

PNG定义了两种类型的数据块,一种是称为关键数据块(critical chunk),这是标准的数据块,另一种叫做辅助数据块(ancillary chunks),这是可选的数据块。关键数据块定义了4个标准数据块,每个PNG文件都必须包含它们,PNG读写软件也都必须要支持这些数据块。虽然PNG文件规范没有要求PNG编译码器对可选数据块进行编码和译码,但规范提倡支持可选数据块。

下表就是PNG中数据块的类别,其中,关键数据块部分我们使用_前缀加以区分。

数据块符号数据块名称多数据块可选否位置限制
_IHDR文件头数据块第一块
cHRM基色和白色点数据块在PLTE和IDAT之前
gAMA图像γ数据块在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(专用公共数据块)无限制
gIFg(专用公共数据块)无限制
gIFt(专用公共数据块)无限制
gIFx(专用公共数据块)无限制
_IEND图像结束数据最后一个数据块

为了简单起见,我们假设在我们使用的PNG文件中,这4个数据块按以上先后顺序进行存储,并且都只出现一次。

(1)IHDR
文件头数据块IHDR(header chunk):它包含有PNG文件中存储的图像数据的基本信息,并要作为第一个数据块出现在PNG数据流中,而且一个PNG数据流中只能有一个文件头数据块。

文件头数据块由13字节组成,它的格式如下表所示。

域的名称字节数说明
Width4 bytes图像宽度,以像素为单位
Height4 bytes图像宽度,以像素为单位
Bit depth1 bytes颜色类型::
0:灰度图像, 1,2,4,8或16
2:真彩色图像,8或16
3:索引彩色图像,1,2,4或8
4:带α通道数据的灰度图像,8或16
6:带α通道数据的真彩色图像,8或16
ColorType1 bytes图像深度:
索引彩色图像:1,2,4或8
灰度图像:1,2,4,8或16
真彩色图像:8或16
Compression method1 bytes压缩方法(LZ77派生算法)
Filter method1 bytes滤波器方法
Interlace method1 bytes隔行扫描方法:
0:非隔行扫描
1:Adam7(由Adam M. Costello开发的7遍隔行扫描方法)

(2)PLTE
对于索引图像,调色板信息是必须的,调色板的颜色索引从0开始编号,然后是1、2……,调色板的颜色数不能超过色深中规定的颜色数(如图像色深为4的时候,调色板中的颜色数不可以超过2^4=16),否则,这将导致PNG图像不合法。

真彩色图像和带α通道数据的真彩色图像也可以有调色板数据块,目的是便于非真彩色显示程序用它来量化图像数据,从而显示该图像。

PLTE数据块是定义图像的调色板信息,PLTE可以包含1~256个调色板信息,每一个调色板信息由3个字节组成:

颜色字节说明
Red1byte0 = 黑色, 255 = 红
Green1byte0 = 黑色, 255 = 绿
Blue1byte0 = 黑色, 255 = 蓝

(3)IDAT
图像数据块IDAT(image data chunk):它存储实际的数据,在数据流中可包含多个连续顺序的图像数据块。

IDAT存放着图像真正的数据信息,因此,如果能够了解IDAT的结构,我们就可以很方便的生成PNG图像。
(4)IEND
图像结束数据IEND(image trailer chunk):它用来标记PNG文件或者数据流已经结束,并且必须要放在文件的尾部。

如果我们仔细观察PNG文件,我们会发现,文件的结尾12个字符看起来总应该是这样的:
00 00 00 00 49 45 4E 44 AE 42 60 82

不难明白,由于数据块结构的定义,IEND数据块的长度总是0(00 00 00 00,除非人为加入信息),数据标识总是IEND(49 45 4E 44),因此,CRC码也总是AE 42 60 82
3.数据块结构

PNG文件中,每个数据块由4个部分组成,如下:

名称字节数说明
Length (长度)4字节指定数据块中数据域的长度,其长度不超过(231-1)字节
Chunk Type Code (数据块类型码)4字节数据块类型码由ASCII字母(A-Z和a-z)组成
Chunk Data (数据块数据)可变长度存储按照Chunk Type Code指定的数据
CRC (循环冗余检测)4字节存储用来检测是否有错误的循环冗余码

CRC(cyclic redundancy check)域中的值是对Chunk Type Code域和Chunk Data域中的数据进行计算得到的。CRC具体算法定义在ISO 3309和ITU-T V.42中,其值按下面的CRC码生成多项式进行计算:

x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1

二.JPEG格式

其实JPEG 和JPG没有区别,JPG的全名、正式扩展名是JPEG。但因DOS、Windows 95等早期系统采用的8.3命名规则只支持最长3字符的扩展名,为了兼容采用了.jpg。也因历史习惯和兼容性考虑,.jpg目前更流行。

总的来说:JPEG是文件格式,JPG是扩展名。

JPG即使用JPEG文件交换格式存储的编码图像文件扩展名。 JPEG联合图象专家组,是一种压缩标准。两种文件应该没有区别,如果做文件扩展名严格地说应是JPG。

JPEG是一个压缩标准,又可分为标准 JPEG、渐进式JPEG及JPEG2000三种:

①标准JPEG:以24位颜色存储单个光栅图像,是与平台无关的格式,支持最高级别的压缩,不过,这种压缩是有损耗的。此类型图片在网页下载时只能由上而下依序显示图片,直到图片资料全部下载完毕,才能看到全貌。

②渐进式 JPEG:渐进式JPG为标准JPG的改良格式,支持交错,可以在网页下载时,先呈现出图片的粗略外观后,再慢慢地呈现出完整的内容,渐进式JPG的文件 比标准JPG的文件要来得小。

③JPEG2000:新一代的影像压缩法,压缩品质更好,其压缩率比标准JPEG高约30%左右,同时支持有损 和无损压缩。一个极其重要的特征在于它能实现渐进传输,即先传输图像的轮廓,然后逐步传输数据,让图像由朦胧到清晰显示。

JPEG(Joint Photographic Experts Group)是联合图像专家小组的英文缩写。它由国际电话与电报咨询委员会CCITT(The International Telegraph and Telephone Consultative Committee)与国际标准化组织ISO于1986年联合成立的一个小组,负责制定静态数字图像的编码标准。

JPEG专家组开发了两种基本的压缩算法、两种数据编码方法、四种编码模式。具体如下:
压缩算法:
(1)有损的离散余弦变换(Discrete Cosine Transform,DCT);
(2)无损的预测技术压缩。
数据编码方法:
(1)哈夫曼编码;
(2)算术编码;
编码模式:
(1)基于DCT顺序模式:编/解码通过一次扫描完成
(2)基于DCT递进模式:编/解码需要多次扫描完成,扫描效果从粗糙到精细,逐级递进
(3)无损模式:基于DPCM,保证解码后完全精确恢复到原图像采样值
(4)层次模式:图像在多个空间多种分辨率进行编码,可以根据需要只对低分辨率数据作解码,放弃高分辨率信息

1.JPEG文件结构介绍

JPEG文件使用的数据存储方式有多种,最常用的格式称为JPEG文件交换格式(JPEG File Interchange Format,JFIF)。而JPEG文件大体上可以分成两个部分:标记码(Tag)和压缩数据。

标记码由两个字节构成,其前一个字节是固定值0xFF,后一个字节则根据不同意义有不同数值。在每个标记码之前还可以添加数目不限的无意义的0xFF填充,也就说连续的多个0xFF可以被理解为一个0xFF,并表示一个标记码的开始。而在一个完整的两字节的标记码后,就是该标记码对应的压缩数据流,记录了关于文件的诸种信息。

常用的标记有SOI、APP0、DQT、SOF0、DHT、DRI、SOS、EOI。

注意,SOI等都是标记的名称。在文件中,标记码是以标记代码形式出现。例如SOI的标记代码为0xFFD8,即在JPEG文件中的如果出现数据0xFFD8,则表示此处为一个SOI标记。

下面附录列出完整的JPEG定义的标记码表:

(1)SOI,Start of Image,图像开始
标记代码|2字节|固定值0xFFD8

(2)APP0,Application,应用程序保留标记0
标记代码|2字节|固定值0xFFE0
包含9个具体字段:
① 数据长度|2字节|①~⑨9个字段的总长度,即不包括标记代码,但包括本字段
② 标识符|5字节|固定值0x4A46494600,即字符串“JFIF0”
③ 版本号|2字节|一般是0x0102,表示JFIF的版本号1.2,可能会有其他数值代表其他版本
④ X和Y的密度单位|1字节|只有三个值可选
0:无单位;
1:点数/英寸;
2:点数/厘米
⑤ X方向像素密度|2字节|取值范围未知
⑥ Y方向像素密度|2字节|取值范围未知
⑦ 缩略图水平像素数目|1字节|取值范围未知
⑧ 缩略图垂直像素数目|1字节|取值范围未知
⑨ 缩略图RGB位图|长度可能是3的倍数|缩略图RGB位图数据

本标记段可以包含图像的一个微缩版本,存为24位的RGB像素。如果没有微缩图像(这种情况更常见),则字段⑦“缩略图水平像素数目”和字段⑧“缩略图垂直像素数目”的值均为0。

(3)APPn,Application,应用程序保留标记n,其中n=1~15(任选)
标记代码|2字节|固定值0xFFE1~0xFFF
包含2个具体字段:
① 数据长度|2字节|①~②2个字段的总长度,即不包括标记代码,但包括本字段
② 详细信息|数据长度-2字节|内容不定

(4)DQT,Define Quantization Table,定义量化表
标记代码|2字节|固定值0xFFDB
包含9个具体字段:
① 数据长度|2字节|字段①和多个字段②的总长度,即不包括标记代码,但包括本字段
② 量化表|数据长度|2字节
a)精度及量化表ID|1字节|
高4位:精度,只有两个可选值
0:8位;
1:16位
低4位:
量化表ID,取值范围为0~3
b)表项|64×(精度+1))字节|例如8位精度的量化表,其表项长度为64×(0+1)=64字节

本标记段中,字段②可以重复出现,表示多个量化表,但最多只能出现4次。

(5)SOF0,Start of Frame,帧图像开始
标记代码|2字节|固定值0xFFC0
包含9个具体字段:
① 数据长度|2字节|①~⑥六个字段的总长度,即不包括标记代码,但包括本字段
② 精度|1字节|每个数据样本的位数,通常是8位,一般软件都不支持 12位和16位
③ 图像高度|2字节|图像高度(单位:像素),如果不支持 DNL 就必须 >0
④ 图像宽度|2字节|图像宽度(单位:像素),如果不支持 DNL 就必须 >0
⑤ 颜色分量数|1字节|只有3个数值可选
1:灰度图;
3:YCrCb或YIQ;
4:CMYK
而JFIF中使用YCrCb,故这里颜色分量数恒为3
⑥颜色分量信息|颜色分量数×3字节(通常为9字节)
a)颜色分量ID|1字节
b)水平/垂直采样因子|1字节|
高4位:水平采样因子
低4位:垂直采样因子
c)量化表|1字节|当前分量使用的量化表的ID

本标记段中,字段⑥应该重复出现,有多少个颜色分量(字段⑤),就出现多少次(一般为3次)。

(6)DHT,Difine Huffman Table,定义哈夫曼表
标记代码|2字节|固定值0xFFC4
包含2个具体字段:
①数据长度|2字节|字段①和多个字段②的总长度,即不包括标记代码,但包括本字段
② 哈夫曼表|数据长度-2字节
a)表ID和表类型|1字节|
高4位:类型,只有两个值可选
0:DC直流;
1:AC交流
低4位:哈夫曼表ID,注意,DC表和AC表分开编码
b)不同位数的码字数量|16字节
c)编码内容|16个不同位数的码字数量之和(字节)

本标记段中,字段②可以重复出现(一般4次),也可以致出现1次。例如,Adobe Photoshop 生成的JPEG图片文件中只有1个DHT标记段,里边包含了4个哈夫曼表;而Macromedia Fireworks生成的JPEG图片文件则有4个DHT标记段,每个DHT标记段只有一个哈夫曼表。

(7)DRI,Define Restart Interval,定义差分编码累计复位的间隔
标记代码|2字节|固定值0xFFDD
包含2个具体字段:
①数据长度|2字节|固定值0x0004,①~②两个字段的总长度, 即不包括标记代码,但包括本字段
②MCU块的单元中的重新开始间隔|2字节|设其值为n,则表示每n个MCU块就有一个,RSTn标记。第一个标记是RST0,第二个是RST1等,RST7后再从RST0重复。

如果没有本标记段,或间隔值为0时,就表示不存在重开始间隔和标记RST

(8)SOS,Start of Scan,扫描开始 12字节
标记代码|2字节|固定值0xFFDA
包含2个具体字段:
①数据长度|2字节|①~④两个字段的总长度,即不包括标记代码,但包括本字段
②颜色分量数|1字节|应该和SOF中的字段⑤的值相同,即:
1:灰度图是;
3: YCrCb或YIQ;
4:CMYK。
而JFIF中使用YCrCb,故这里颜色分量数恒为3
③颜色分量信息
a) 颜色分量ID|1字节
b) 直流/交流系数表号|1字节|
高4位:直流分量使用的哈夫曼树编号
低4位:交流分量使用的哈夫曼树编号
④ 压缩图像数据
a)谱选择开始|1字节|固定值0x00
b)谱选择结束|1字节|固定值0x3F
c)谱选择|1字节|在基本JPEG中总为00

本标记段中,字段③应该重复出现,有多少个颜色分量(字段②),就出现多少次(一般为3次)。本段结束后,紧接着就是真正的图像信息了。图像信息直至遇到一个标记代码就自动结束,一般就是以EOI标记表示结束。

(9)EOI,End of Image,图像结束 2字节
标记代码|2字节|固定值0xFFD9

这里补充说明一下,由于在JPEG文件中0xFF具有标志性的意思,所以在压缩数据流(真正的图像信息)中出现0xFF,就需要作特别处理。具体方法是,在数据0xFF后添加一个没有意义的0x00。换句话说,如果在图像数据流中遇到0xFF,应该检测其紧接着的字符,如果是
1)0x00,则表示0xFF是图像流的组成部分,需要进行译码;
2)0xD9,则与0xFF组成标记EOI,则图像流结束,同时图像文件结束;
3)0xD0~0xD7,则组成RSTn标记,则要忽视整个RSTn标记,即不对当前0xFF和紧接的0xDn两个字节进行译码,并按RST标记的规则调整译码变量;
3)0xFF,则忽视当前0xFF,对后一个0xFF再作判断;
4)其他数值,则忽视当前0xFF,并保留紧接的此数值用于译码。

2.JPEG图像编码

在实际应用中,JPEG图像编码算法使用的大多是离散余弦变换、Huffman编码、顺序编码模式。这样的方式,被人们称为JPEG的基本系统。这里介绍的JPEG编码算法的流程,也是针对基本系统而言。基本系统的JPEG压缩编码算法一共分为11个步骤:颜色模式转换、采样、分块、离散余弦变换(DCT)、Zigzag 扫描排序、量化、DC系数的差分脉冲调制编码、DC系数的中间格式计算、AC系数的游程长度编码、AC系数的中间格式计算、熵编码。

(1)颜色模式转换

JPEG采用的是YCrCb颜色空间,而BMP采用的是RGB颜色空间,要想对BMP图片进行压缩,首先需要进行颜色空间的转换。YCrCb颜色空间中,Y代表亮度,Cr,Cb则代表色度和饱和度(也有人将Cb,Cr两者统称为色度),三者通常以Y,U,V来表示,即用U代表Cb,用V代表Cr。RGB和YCrCb之间的转换关系如下所示:

Y = 0.299R+0.587G+0.114B

Cb = -0.1687R-0.3313G+0.5B+128

Cr = 0.5R=0.418G-0.0813B+128

一般来说,C 值 (包括 Cb Cr) 应该是一个有符号的数字, 但这里通过加上128,使其变为8位的无符号整数,从而方便数据的存储和计算。反之:

R = Y+1.402(Cr-128)

G = Y-0.34414(Cb-128)-0.71414(Cr-128)

B = Y+1.772(Cb-128)

(2)采样

研究发现,人眼对亮度变换的敏感度要比对色彩变换的敏感度高出很多。因此,我们可以认为Y分量要比Cb,Cr分量重要的多。在BMP图片中,RGB三个分量各采用一个字节进行采样,也就是我们常听到的RGB888的模式;而JPEG图片中,通常采用两种采样方式:YUV411和YUV422,它们所代表的意义是Y,Cb,Cr三个分量的数据取样比例一般是4:1:1或者4:2:2(4:1:1含义就是:在2x2的单元中,本应分别有4个Y,4个U,4个V值,用12个字节进行存储。经过4:1:1采样处理后,每个单元中的值分别有4个Y、1个U、1个V,只要用6个字节就可以存储了)。这样的采样方式,虽然损失了一定的精度但也在人眼不太察觉到的范围内减小了数据的存储量。当然,JPEG格式里面也允许将每个点的U,V值都记录下来。

(3)分块

由于后面的DCT变换是是对8x8的子块进行处理的,因此,在进行DCT变换之前必须把源图象数据进行分块。源图象中每点的3个分量是交替出现的,先要把这3个分量分开,存放到3张表中去。然后由左及右,由上到下依次读取8x8的子块,存放在长度为64的表中,即可以进行DCT变换。注意,编码时,程序从源数据中读取一个8x8的数据块后,进行DCT变换,量化,编码,然后再读取、处理下一个8*8的数据块。

JPEG 编码是以每8x8个点为一个单位进行处理的. 所以如果原始图片的长宽不是 8 的倍数, 都需要先补成8的倍数, 使其可以进行一块块的处理。将原始图像数据分为8*8的数据单元矩阵之后,还必须将每个数值减去128,然后一一带入DCT变换公式,即可达到DCT变换的目的。图像的数据值必须减去128,是因为DCT公式所接受的数字范围是-128到127之间。

(4)离散余弦变换

DCT(Discrete Cosine Transform,离散余弦变换),是码率压缩中常用的一种变换编码方法。任何连续的实对称函数的傅里叶变换中只含有余弦项,因此,余弦变换同傅里叶变换一样具有明确的物理意义。DCT是先将整体图像分成N*N的像素块,然后针对N*N的像素块逐一进行DCT操作。需要提醒的是,JPEG的编码过程需要进行正向离散余弦变换,而解码过程则需要反向离散余弦变换。

正向离散余弦变换计算公式:

F(u,v)=c(u)c(v)N1i=0N1j=0f(i,j)cos[(2i+1)π2Nu]cos[(2j+1)π2Nv]

c(u)=1N,u=0
c(u)=2N,u0

反向离散余弦变换计算公式:

f(i,j)=N1u=0N1v=0c(u)c(v)F(u,v)cos[(2i+1)π2Nu]cos[(2j+1)π2Nv]

c(u)=1NJPEG、GIF、PNG、BMP哪种图片格式的图片清晰一点?

JPEG、GIF、PNG、BMP哪种图片格式的图片清晰一点?

图片格式无损转换的方法

JPG、GIF、PNG和BMP格式的图片各有啥优点和缺点?

常见图片格式详解

Tensorflow Keras 错误:未知的图像文件格式。需要 JPEG、PNG、GIF、BMP 之一