文章目录
介绍
JPEG 的全称是 Joint Photographic Experts Group,是一种常用的图像存储格式, jpg/jpeg是24位的图像文件格式,也是一种高效率的压缩格式。JPEG 是面向连续色调静止图像的一种压缩标准。其最初是使用64 Kbps的通信线路传输 720×576 分辨率压缩后的图像。通过损失极少的分辨率,可以将图像所需存储量减少至原大小的10%。 .jpg/.jpeg 文件并不适合放大观看,输出成印刷品时品质也会受到影响。一般情况下,.jpg/*.jpeg文件只有几十KB,而色彩数最高可达到24位,所以被广泛运用在Internet上。JPEG 的文件格式一般有两种文件扩展名:.jpg和.jpeg。这两种扩展名从本质上讲没有去别的,我们是可以把 .jpg 的文件改名为 .jpeg,而对文件本身不会有任何影响。
类型
标准JPEG
以24位颜色存储单个光栅图像,是与平台无关的格式,支持最高级别的压缩,不过,这种压缩是有损耗的。此类型图片在网页下载时只能由上而下依序显示图片,直到图片资料全部下载完毕,才能看到全貌。
渐进式JPEG
此类型在网页下载时,先呈现出图像的粗略外观后,再慢慢地呈现出完整的内容,而且存成渐进式JPG格式的文档比存成标准JPG格式的文档要来得小,所以如果要在网页上使用图像,可以多用这种格式。
JPEG2000
新一代的影像压缩法,压缩品质更好,其压缩率比标准JPEG高约30%左右,同时支持有损和无损压缩。一个极其重要的特征在于它能实现渐进传输,即先传输图像的轮廓,然后逐步传输数据,让图像由朦胧到清晰显示。它可以改善在无线传输时,因信号不稳造成马赛克现象及位置错乱的情况,改善传输的品质。
压缩类型
顺序式编码(SequentialEncoding)
编码,解码通过从左到右,从上到下一次扫描完成。
递增式编码(ProgressiveEncoding)
编码,解码需要多次扫描完成,扫描效果从模糊逐渐清晰。
无失真编码(LosslessEncoding)
解码后能完全恢复到原图像的采样值。
阶梯式编码(HierarchicalEncoding)
图像在多个空间分辨率中进行编码,可以根据实际需要选择不同分辨率进行解码。
压缩步骤
颜色转换
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)
DCT变换
DCT(Discrete Cosine Transform,离散余弦变换),是码率压缩中常用的一种变换编码方法。任何连续的实对称函数的傅里叶变换中只含有余弦项,因此,余弦变换同傅里叶变换一样具有明确的物理意义。DCT是先将整体图像分成NN的像素块,然后针对NN的像素块逐一进行DCT操作。需要提醒的是,JPEG的编码过程需要进行正向离散余弦变换,而解码过程则需要反向离散余弦变换。
量化
图像数据转换为DCT频率系数之后,还要进行量化阶段,才能进入编码过程。量化阶段需要两个8*8量化矩阵数据,一个是专门处理亮度的频率系数,另一个则是针对色度的频率系数,将频率系数除以量化矩阵的值之后取整,即完成了量化过程。当频率系数经过量化之后,将频率系数由浮点数转变为整数,这才便于执行最后的编码。不难发现,经过量化阶段之后,所有的数据只保留了整数近似值,也就再度损失了一些数据内容。在JPEG算法中,由于对亮度和色度的精度要求不同,分别对亮度和色度采用不同的量化表。前者细量化,后者粗量化。
编码
在得到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表的值。
格式
JPEG图片格式组成部分:SOI(文件头)+APP0(图像识别信息)+ DQT(定义量化表)+ SOF0(图像基本信息)+ DHT(定义Huffman表) + DRI(定义重新开始间隔)+ SOS(扫描行开始)+ EOI(文件尾)。其中粗体部分是必须的,下面我就来解释一下这些信息吧。
SOI文件头
JPEG文件的开始2个字节都是FF D8这是JPEG协议规定的。
名称 | 字节数 | 值 |
---|---|---|
段标识 | 1 | FF |
段类型 | 1 | D8 |
APP0图像识别信息
名称 | 字节数 | 值 | 说明 |
---|---|---|---|
段标识 | 1 | FF | - |
段类型 | 1 | E0 | - |
段长度 | 2 | 0010 | 示例表示16个字节。如果有RGB缩略图,此处为16+3n |
交换格式 | 5 | 4A46494600 | 示例表示JFIF的ASII码,还可以是TFIF(使用频率很低) |
主版本号 | 1 | 01 | 示例表示主版本号为1 |
次版本 | 1 | 01 | 示例表示次版本号为1 |
密度单位 | 1 | 01 | 示例表示密度单位为点数/英寸 0 —— 无单位 1 —— 点数/英寸 2 —— 点数/厘米 |
X像素密度 | 2 | 0060 | 示例表示水平像素密度是96 |
Y像素密度 | 2 | 0060 | 示例表示垂直像素密度是96 |
缩略图X像素 | 1 | 00 | 示例表示没有缩略图 |
缩略图Y像素 | 1 | 00 | 没有缩略图 |
RGB缩略图 | 3n | - | n(缩略图像素总数)=缩略图X像素*缩略图Y像素 |
DQT定义量化表
名称 | 字节数 | 值 | 说明 |
---|---|---|---|
段标识 | 1 | FF | |
段类型 | 1 | DB | |
段长度 | 2 | 0043 | 其值=3+n(当只有一个QT时) |
QT信息 | 0-3位 | QT号 | 0=8bit,1字节;否则=16bit,2字节 |
4-7位 | QT精度 | ||
QT | n | n=64×QT精度的字节数 |
SOF0图像基本信息
名称 | 字节数 | 值 | 说明 |
---|---|---|---|
段标识 | 1 | FF | |
段类型 | 1 | C0 | |
段长度 | 2 | 0011 | 17 = 8 + 3*3,说明组件数量有3个 |
样本精度 | 1 | 08 | 每个样本的信息是8bit,大多数软件不支持12和16 |
图片高度 | 2 | 01E0 | 480图片高度与实际一致 |
图片宽度 | 2 | 0140 | 320图片宽度与实际一致 |
组件数量 | 1 | 03 | 1 —— 灰度图 3 —— YCbCr彩色图 4 —— CMYK彩色图 |
组件 ID | 1 | - | 1 —— Y 2 —— Cb 3 —— Cr 4 —— I 5 —— Q |
采样系数 | 0-3位 | - | 垂直采样系数 |
4-7位 | - | 水平采样系数 | |
量化表号 | 1 | - | - |
DHT定义huffman表
名称 | 字节数 | 值 | 说明 |
---|---|---|---|
段标识 | 1 | FF | |
段类型 | 1 | C4 | |
段长度 | 2 | 00 1F | 31 = 19(段长度2个字节+HT信息1个字节+HT位表16个字节) + 12(这个数代表HT表有12个字节) |
HT信息 | 0-3位 | - | HT号 |
第4位 | - | 0 —— DC表 1 —— AC表 | |
5-7位 | - | 必须为0 | |
HT位表 | 16 | - | 16个数字值和小于等于256 |
HT值表 | n | n=表头16个数的和 |
SOS扫描行开始
名称 | 字节数 | 值 | 说明 |
---|---|---|---|
段标识 | 1 | FF | |
段类型 | 1 | DA | |
段长度 | 2 | 000C | 12 = 6(2个字节的扫描行开始头+1个字节扫描行内组件数量+3个字节的剩余位) + 2×3(扫描行内组件数量,每个组件2个字节) |
扫描行内组件数量 | 1 | 3 | 必须∈[1,4],否则错误,通常=3 |
组件 ID | 1 | - | 1 —— Y 2 —— Cb 3 —— Cr 4 —— I 5 —— Q |
Huffman表号 | 0-3位 | AC表号 (其值=0...3) | |
4-7位 | DC表号(其值=0...3) | ||
剩余字节 | 3 | 最后3个字节用途暂时不明 |
EOI文件尾
名称 | 字节数 | 值 |
---|---|---|
段标识 | 1 | FF |
段类型 | 1 | D9 |
其它段
COM(注释)
名称 | 字节数 | 值 | 说明 |
---|---|---|---|
段标识 | 1 | FF | |
段类型 | 1 | FE | |
段长度 | 2 | - | 其值=注释字符的字节数+2 |
段内容 | n | - | 注释字符 |
DRI(定义重新开始间隔)
名称 | 字节数 | 值 | 说明 |
---|---|---|---|
段标识 | 1 | FF | |
段类型 | 1 | DD | |
段长度 | 2 | - | - |
开始间隔 | 2 | - | 复位标记的间隔距离 |