2019-09-15

图片

一、PNG


特性

1、使用调色板技术可支持256种颜色的彩色图像。

2、流式读/写性(streamability):图像文件格式允许连续读出和写入图像数据。(因此适于网络传播)

3、逐次逼近显示(progressive display):这种特性可使在通信链路上传输图像文件的同时就在终端上显示图像,把整个轮廓显示出来之后逐步显示图像的细节,也就是先用低分辨率显示图像,然后逐步提高它的分辨率。(类似马赛克逐渐消除的过程)

4、透明性(transparency):这个性能可使图像中某些部分不显示出来,用来创建一些有特色的图像。

5、辅助信息(ancillary information):这个特性可用来在图像文件中存储一些文本注释信息。(就是可以说一些废话)

6、使用无损压缩。

7、可在一个文件中存储多幅图像。

文件结构

PNG图像格式文件由文件署名和数据块(chunk)组成。

文件署名域

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

十六进制:8950 4e47 0d0a 1a0a

数据块

这里有两种类型的数据块,一种是称为关键数据块(critical chunk),就是必须要有的块;另一种叫做辅助数据块(ancillary chunks)。

每个数据块都由下表所示的的4个域组成。

名称字节数说明

1

关键数据块

关键数据块中的4个标准数据块是:

(1) 文件头数据块IHDR(header chunk):

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

文件头数据块由13字节,组成结构如下:

2

(2) 调色板数据块PLTE(palette chunk):

它包含有与索引彩色图像((indexed-color image))相关的彩色变换数据,它仅与索引彩色图像有关,而且要放在图像数据块(image data chunk)之前。真彩色的PNG数据流也可以有调色板数据块,目的是便于非真彩色显示程序用它来量化图像数据,从而显示该图像。结构如下:

颜色字节意义

Red    1 byte 0 = 黑色, 255 = 红

Green 1 byte 0 = 黑色, 255 = 绿色

Blue    1 byte 0 = 黑色, 255 = 蓝色

PLTE数据块是定义图像的调色板信息,PLTE可以包含1~256个调色板信息,每一个调色板信息由3个字节组成,因此调色板数据块所包含的最大字节数为768,调色板的长度应该是3的倍数,否则,这将是一个非法的调色板。

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

(3) 图像数据块IDAT(image data chunk):

它存储实际的数据,在数据流中可包含多个连续顺序的图像数据块。

IDAT存放着图像真正的数据信息,因此,如果能够了解IDAT的结构,我们就可以很方便的生成PNG图像。

(4) 图像结束数据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。

辅助数据块

PNG文件格式规范制定的10个辅助数据块是:

1.背景颜色数据块bKGD(background color)。

2.基色和白色度数据块cHRM(primary chromaticities and white point)。所谓白色度是指当R=G=B=最大值时在显示器上产生的白色度。

3.图像γ数据块gAMA(image gamma)。

4.图像直方图数据块hIST(image histogram)。

5.物理像素尺寸数据块pHYs(physical pixel dimensions)。

6.样本有效位数据块sBIT(significant bits)。

7.文本信息数据块tEXt(textual data)。

8.图像最后修改时间数据块tIME (image last-modification time)。

9.图像透明数据块tRNS (transparency)。

10.压缩文本数据块zTXt (compressed textual data)。

数据块摘要

关键数据块、辅助数据块和专用公共数据块(special-purpose public chunks)综合下表中:

3

tEXt和zTXt数据块中的标准关键字:

4


PNG-32

PNG-32每个像素的深度为32bits,其中RGBA四个通道各占8bits。所谓的RGBA四个通道,就是红,绿,蓝,透明 这四种色值各自的大小,都用8bits来表示(0~255)。

PNG-24

同理,PNG-24的像素深度为24bits,其中RGB三个通道各占8bits。PNG-24因为没有Alpha通道(透明通道),所以不支持透明图片。

PNG-8

上述两种像素格式都非常好理解,但是似乎按照那种方式来存储图片并不会让图片变小。PNG-8则作出了一些变动,他将图片中用到的每种颜色都存储在一个长度为255的数组中,称之为调色板,然后每个像素上存储对应颜色在调色板上的位置。因为颜色上限是255种,所以每个像素只需要8bits就可以表示对应的颜色信息。这种表示颜色的方式也被称之为索引色。

PNG-8相比之下确实使用了更少的空间来存储颜色,但是他能表达的颜色种类是有上限的,所以在将PNG-32转换成PNG-8时会在一些颜色过渡的地方会明显的看到不平滑的渐变。

PNG图片压缩

???


二、JPEG

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

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

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

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

JPEG其基本数据结构为两大类型:“段”和经过压缩编码的图像数据。

段的一般结构

-----------------------------------------------------------------

名称   字节数数据  说明

-----------------------------------------------------------------

段标识  1    FF   每个新段的开始标识

段类型  1          类型编码(称作“标记码”)

段长度  2          包括段内容和段长度本身,不包括段标识和段类型

段内容              ≤65533字节

-----------------------------------------------------------------


段类型

---------------------------------------

名称  标记码  说明

---------------------------------------

SOI     D8    文件头

EOI     D9    文件尾

SOF0  C0    帧开始(标准 JPEG)

SOF1  C1    同上

DHT   C4    定义 Huffman 表(霍夫曼表)

SOS   DA    扫描行开始(图像压缩数据)

DQT   DB    定义量化表  YUV

DNL DC 定义扫描行数

DRI    DD    定义重新开始间隔

APP0  E0    定义交换格式和图像识别信息

APP1  E1 数码相机专用的Exif格式

COM   FE    注释

-----------------------------------------------------------

以下按一般JPEG文件的段排列顺序详细介绍 各种段的结构:

SOI(文件头)

-----------------

名称  字节数   值

-----------------

段 标识   1     FF

段类型   1     D8 

-----------------

说明:这两个字节构成了 JPEG文件头。

APP0(图像识别信息)

--------------------------------------------------------------------------

名 称       字节数 值          说明

--------------------------------------------------------------------------

段标识        1   FF

段类型        1   E0

段长度        2   0010        如果有 RGB缩略图就=16+3n

(以下为段内容)

交换格式      5   4A46494600  “JFIF”的ASCII码

主 版本号      1

次版本号      1  

密度单位      1               0=无单位;1=点数/英 寸;2=点数/厘米

X像素密度     2               水平方向的密度   

Y像素密 度     2               垂直方向的密度

缩略图X像素   1               缩略图水平像素数目  

缩略图Y像素   1               缩略图垂直像素数目

(如果“缩略图X像素”和“缩略图Y像素”的值均>0,那么才有下面的数 据)

RGB缩略图    3×n             n=缩略图像素总数=缩略图X像素×缩略图Y像素

--------------------------------------------------------------------------

说明:

①JFIF是JPEG File Interchange Format的缩写,即JPEG文件交换格式,另外还有TIFF等格式,很少用

②“如果有RGB缩略图就=16+3n”是什么意思呢?比如说“缩略图X像素”和“缩略图Y像素”的值均为48,就表示有一个48×48像素的 缩略图(n=48×48),缩略图是24位真彩位图,用3个字节来表示一个像素,所以共占用3n个字节。但大多数JPG文件都没有这个“鸡肋”缩略图。

COM(注释)

--------------------------------------------------------------------------

名 称    字节数   值    说明

--------------------------------------------------------------------------

段 标识    1      FF

段类型    1      FE

段长度    2            其值=注释字符的字节数+2

段 内容                 注释字符

--------------------------------------------------------------------------

说明:有的JPEG文件没有这个段。

DQT(定义量化表)

--------------------------------------------------------------------------

名 称    字节数   值    说明

--------------------------------------------------------------------------

段标识    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=64×QT精度的字节数

--------------------------------------------------------------------------

说明:

①JPEG文件一般有2个DQT段,为Y值(亮度)定义1个, 为C值(色度)定义1个。 

②一个DQT段可以包含多个 QT, 每个都有自己的信息字节

SOF0(图像基本信息)

--------------------------------------------------------------------------

名 称  字节数   值    说明

--------------------------------------------------------------------------

段 标识   1     FF

段类型   1     C0

段长度   2           其值=8+组件数量×3

(以 下为段内容)

样本精度  1    8     每个样本位数(大多数软件不支持12和16)

图片高度  2

图片宽度  2

组件数量  1    3     1=灰度图,3=YCbCr/YIQ 彩色图,4=CMYK 彩色图

(以下每个组件占用3字节)

组 件 ID   1          1=Y, 2=Cb, 3=Cr, 4=I, 5=Q

采样系数  1          0-3位:垂直采 样系数

4-7位:水平采样系数

量化表号  1

---------------------------------------------------------------------------

说明:

①JPEG大都采用yCrCb色彩模型(y表示亮度,Cr红色分量,Cb表示蓝色分量),所以组件数量一般=3

②样本就是单个像素的颜色分量,也可理解为一个样本就是一个组件

③采样系数是实际采样方式与最高采样系数之比,而最高采样系数一般=0.5(分数表示为1/2)。 比如说,垂直采样系数=2,那么2×0.5=1,表示实际采样方式是每个点采一个样,也就是逐点采样;如果垂直采样系数=1,那 么:1×0.5=0.5(分数表示为1/2),表示每2个点采一个样

DHT(定义Huffman表)

--------------------------------------------------------------------------

名 称    字节数   值    说明

--------------------------------------------------------------------------

段 标识    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个数的和

--------------------------------------------------------------------------

说明:

①JPEG文件里有2类Haffman 表:一类用于DC(直流量),一类用于AC(交流量)。一般有4个表:亮度的DC和AC,色度的 DC和AC。最多可有6个。

②一个DHT 段可以包含多个HT表, 每个都有自己的信息字节

③HT表是一个按递增次序代码长度排列的符号表。

SOS(扫描行开始)

--------------------------------------------------------------------------

名 称          字节数   值    说明

--------------------------------------------------------------------------

段 标识           1     FF

段类型           1     DA

段长 度           2     000C  其值=6+2×扫描行内组件数量

(以下为段内容)

扫描行内组件数 量 1     3     必须≥1,≤4(否则错误),通常=3

(以下每个组件占用2字节)

组件 ID           1           1 = Y, 2 = Cb, 3 = Cr, 4 = I, 5 = Q

Huffman表 号      1           0-3位:AC表号 (其值=0...3)

4-7 位:DC表号(其值=0...3)

--------------------------------------------------------------------------

说明:紧接SOS段后的是压缩的图像数据(一个个扫描行),数据存放顺序是从左到右、从上到下。

EOI(文件尾)

------------------

名 称  字节数   值

------------------

段标识   1     FF

段类型   1     D9 

------------------

说明:这两个字节构成了JPEG文件尾。

JPEG编解码

压缩算法:

(1)有损的离散余弦变换DCT(Discrete Cosine Transform)

(2)无损的预测压缩技术;

熵编码方法:

(1)Huffman编码;

(2)算术编码;

编码模式:

(1)基于DCT的顺序模式:编码、解码通过一次扫描完成;

(2)基于DCT的渐进模式:编码、解码需要多次扫描完成,扫描效果由粗到精,逐级递增;

(3)无损模式:基于DPCM,保证解码后完全精确恢复到原图像采样值;

(4)层次模式:图像在多个空间分辨率中进行编码,可以根据需要只对低分辨率数据做解码,放弃高分辨率信息;

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


(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的编码过程需要进行正向离散余弦变换,而解码过程则需要反向离散余弦变换。

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


1

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


2
3

这里的N是水平、垂直方向的像素数目,一般取值为8。8*8的二维像素块经过DCT操作之后,就得到了8*8的变换系数矩阵。这些系数,都有具体的物理含义,例如,U=0,V=0时的F(0,0)是原来的64个数据的均值,相当于直流分量,也有人称之为DC系数或者直流系数。随着U,V的增加,相另外的63个系数则代表了水平空间频率和垂直空间频率分量(高频分量)的大小,多半是一些接近于0的正负浮点数,我们称之为交流系数AC。DCT变换后的8*8的系数矩阵中,低频分量集中在矩阵的左上角。高频成分则集中在右下角。

这里,我们暂时先只考虑水平方向上一行数据(8个像素)的情况时的DCT变换,从而来说明其物理意义。如下图所示:

原始的图像信号(最左边的波形)经过DCT变换之后变成了8个波,其中第一个波为直流成分,其余7个为交流成分。

可见图像信号被分解为直流成分和一些从低频到高频的各种余弦成分。而DCT系数只表示了该种成分所占原图像信号的份额大小。显然,恢复图像信息可以表示为下面的式子:

F(n) = C(n)*E(n),这里,E(n)是一个基底,C(n)是DCT系数,F(n)则是图像信号;如果考虑垂直方向的变化,那就需要一个二维的基底。大学里面的信号处理,傅里叶变换等课程上也讲过,任何信号都可以被分解为基波和不同幅度的谐波的组合,而DCT变换的物理意义也正是如此。

由于大多数图像的高频分量比较小,相应的图像高频分量的DCT系数经常接近于0,再加上高频分量中只包含了图像的细微的细节变化信息,而人眼对这种高频成分的失真不太敏感,所以,可以考虑将这一些高频成分予以抛弃,从而降低需要传输的数据量。这样一来,传送DCT变换系数的所需要的编码长度要远远小于传送图像像素的编码长度。到达接收端之后通过反离散余弦变换就可以得到原来的数据,虽然这么做存在一定的失真,但人眼是可接受的,而且对这种微小的变换是不敏感的。

(5)Zigzag扫描排序

         DCT 将一个 8x8 的数组变换成另一个 8x8 的数组. 但是内存里所有数据都是线形存放的, 如果我们一行行的存放这 64 个数字, 每行的结尾的点和下行开始的点就没有什么关系, 所以 JPEG 规定按如下图中的数字顺序依次保存和读取64 个DCT的系数值。

这样数列里的相邻点在图片上也是相邻的了。不难发现,这种数据的扫描、保存、读取方式,是从8*8矩阵的左上角开始,按照英文字母Z的形状进行扫描的,一般将其称之为Zigzag扫描排序。如下图所示:

(6)量化

        图像数据转换为DCT频率系数之后,还要进行量化阶段,才能进入编码过程。量化阶段需要两个8*8量化矩阵数据,一个是专门处理亮度的频率系数,另一个则是针对色度的频率系数,将频率系数除以量化矩阵的值之后取整,即完成了量化过程。当频率系数经过量化之后,将频率系数由浮点数转变为整数,这才便于执行最后的编码。不难发现,经过量化阶段之后,所有的数据只保留了整数近似值,也就再度损失了一些数据内容。在JPEG算法中,由于对亮度和色度的精度要求不同,分别对亮度和色度采用不同的量化表。前者细量化,后者粗量化。

    下图给出JPEG的亮度量化表和色度量化表,该量化表是从广泛的实验中得出的。当然,你也可以自定义量化表。

这两张表依据心理视觉阀制作, 对 8bit 的亮度和色度的图象的处理效果不错。量化表是控制 JPEG 压缩比的关键,这个步骤除掉了一些高频量, 损失了很多细节信息。但事实上人眼对高频信号的敏感度远没有低频信号那么敏感。所以处理后的视觉损失很小,从上面的量化表也可以看出,低频部分采用了相对较短的量化步长,而高频部分则采用了相对较长的量化步长,这样做,也是为了在一定程度上得到相对清晰的图像和更高的压缩率。另一个重要原因是所有的图片的点与点之间会有一个色彩过渡的过程,而大量的图象信息被包含在低频率空间中,经过DCT处理后, 在高频率部分, 将出现大量连续的零。

(7)DC系数的差分脉冲调制编码

        8*8的图像块经过DCT变换之后得到的DC系数有两个特点:

(1)系数的数值比较大;

(2)相邻的8*8图像块的DC系数值变化不大;

根据这两个特点,DC系数一般采用差分脉冲调制编码DPCM(Difference Pulse Code Modulation),即:取同一个图像分量中每个DC值与前一个DC值的差值来进行编码。对差值进行编码所需要的位数会比对原值进行编码所需要的位数少了很多。假设某一个8*8图像块的DC系数值为15,而上一个8*8图像块的DC系数为12,则两者之间的差值为3。

(8)AC系数的行程长度编码(RLC)

        量化之后的AC系数的特点是,63个系数中含有很多值为0的系数。因此,可以采用行程编码RLC(Run Length Coding)来更进一步降低数据的传输量。利用该编码方式,可以将一个字符串中重复出现的连续字符用两个字节来代替,其中,第一个字节代表重复的次数,第二个字节代表被重复的字符串。例如,(4,6)就代表字符串“6666”。但是,在JPEG编码中,RLC的含义就同其原有的意义略有不同。在JPEG编码中,假设RLC编码之后得到了一个(M,N)的数据对,其中M是两个非零AC系数之间连续的0的个数(即,行程长度),N是下一个非零的AC系数的值。采用这样的方式进行表示,是因为AC系数当中有大量的0,而采用Zigzag扫描也会使得AC系数中有很多连续的0的存在,如此一来,便非常适合于用RLC进行编码。


(9)熵编码

        在得到DC系数的中间格式和AC系数的中间格式之后,为进一步压缩图象数据,有必要对两者进行熵编码。JPEG标准具体规定了两种熵编码方式:Huffman编码和算术编码。JPEG基本系统规定采用Huffman编码(因为不存在专利问题),但JPEG标准并没有限制JPEG算法必须用Huffman编码方式或者算术编码方式。 

Huffman编码:对出现概率大的字符分配字符长度较短的二进制编码,对出现概率小的字符分配字符长度较长的二进制编码,从而使得字符的平均编码长度最短。Huffman编码的原理请参考数据结构中的Huffman树或者最优二叉树。

Huffman编码时DC系数与AC系数分别采用不同的Huffman编码表,对于亮度和色度也采用不同的Huffman编码表。因此,需要4张Huffman编码表才能完成熵编码的工作。具体的Huffman编码采用查表的方式来高效地完成。然而,在JPEG标准中没有定义缺省的Huffman表,用户可以根据实际应用自由选择,也可以使用JPEG标准推荐的Huffman表。或者预先定义一个通用的Huffman表,也可以针对一副特定的图像,在压缩编码前通过搜集其统计特征来计算Huffman表的值。

你可能感兴趣的:(2019-09-15)