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,而对文件本身不会有任何影响。
以24位颜色存储单个光栅图像,是与平台无关的格式,支持最高级别的压缩,不过,这种压缩是有损耗的。此类型图片在网页下载时只能由上而下依序显示图片,直到图片资料全部下载完毕,才能看到全貌。
此类型在网页下载时,先呈现出图像的粗略外观后,再慢慢地呈现出完整的内容,而且存成渐进式JPG格式的文档比存成标准JPG格式的文档要来得小,所以如果要在网页上使用图像,可以多用这种格式。
新一代的影像压缩法,压缩品质更好,其压缩率比标准JPEG高约30%左右,同时支持有损和无损压缩。一个极其重要的特征在于它能实现渐进传输,即先传输图像的轮廓,然后逐步传输数据,让图像由朦胧到清晰显示。它可以改善在无线传输时,因信号不稳造成马赛克现象及位置错乱的情况,改善传输的品质。
编码,解码通过从左到右,从上到下一次扫描完成。
编码,解码需要多次扫描完成,扫描效果从模糊逐渐清晰。
解码后能完全恢复到原图像的采样值。
图像在多个空间分辨率中进行编码,可以根据实际需要选择不同分辨率进行解码。
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(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(文件尾)。其中粗体部分是必须的,下面我就来解释一下这些信息吧。
JPEG文件的开始2个字节都是FF D8这是JPEG协议规定的。
| 名称 | 字节数 | 值 |
|---|---|---|
| 段标识 | 1 | FF |
| 段类型 | 1 | D8 |
| 名称 | 字节数 | 值 | 说明 |
|---|---|---|---|
| 段标识 | 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像素 |
| 名称 | 字节数 | 值 | 说明 |
|---|---|---|---|
| 段标识 | 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精度的字节数 |
| 名称 | 字节数 | 值 | 说明 |
|---|---|---|---|
| 段标识 | 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 | - | - |
| 名称 | 字节数 | 值 | 说明 |
|---|---|---|---|
| 段标识 | 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个数的和 |
| 名称 | 字节数 | 值 | 说明 |
|---|---|---|---|
| 段标识 | 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个字节用途暂时不明 |
| 名称 | 字节数 | 值 |
|---|---|---|
| 段标识 | 1 | FF |
| 段类型 | 1 | D9 |
| 名称 | 字节数 | 值 | 说明 |
|---|---|---|---|
| 段标识 | 1 | FF | |
| 段类型 | 1 | FE | |
| 段长度 | 2 | - | 其值=注释字符的字节数+2 |
| 段内容 | n | - | 注释字符 |
| 名称 | 字节数 | 值 | 说明 |
|---|---|---|---|
| 段标识 | 1 | FF | |
| 段类型 | 1 | DD | |
| 段长度 | 2 | - | - |
| 开始间隔 | 2 | - | 复位标记的间隔距离 |