JPEG系列一 JPEG图片的文件格式

本文深入解析JPEG图片的文件格式和内部结构,介绍了JPEG压缩标准及其文件交换格式JFIF,详细阐述了JPEG文件布局和重要标记,包括SOI、APP0、DQT等,并概述了EXIF数据和压缩图像数据的存储方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JPEG图片的文件格式


互联网上广泛使用的image/jpeg 图片,准确来说,全称应该叫做使用 JPEG标准压缩图像,使用JFIF标准封装图像数据的图形文件。

 

JPEG 是一个压缩标准,JFIF 是一个文件格式标准,总体来说它们不是一个概念。

 

JPEG 是Joint Photographic Experts Group(联合图像专家小组)的缩写,是第一个国际图像压缩标准。JPEG图像压缩算法能够在提供良好的压缩性能的同时,具有比较好的重建质量,被广泛应用于图像、视频处理领域。JPEG是有损压缩,压缩后的数据在恢复时会丢失一部分不重要的信息。

 

JFIF 是 JPEG File Interchange Format 的缩写,也即 JPEG 文件交换格式。JFIF 是一个图片文件格式标准,它是一种使用 JPEG 图像压缩技术存储摄影图像的方法。JFIF 代表了一种"通用语言"文件格式,它是专门为方便用户在不同的计算机和应用程序间传输 JPEG 图像而设计的语言。

JFIF 文件格式定义图形数据如何存储,包括图片长宽、分辨率、颜色空间等基本信息,这些是 JPEG 压缩标准未定义的。JFIF中使用”标记”来保存图片的各种属性信息。

 

 

JPEG图片的文件布局

一个典型的EXIF JPEG文件布局

JPEG SOI : FF D8  //  图片起始

JPEG APP0:0xFFE0  // 

    APP0 SIZE:1D 23  //当前标记的长度

    JFIF Flag:JFIF  // JFIF 标识

    VERSION:// 版本号

    ATTRIBUTION: // 长宽、DPI等信息


JPEG APP1: FF E1
  APP1 Size : 1C 45  //  注意:前面这三个WORD都是big endian的
  EXIF Flag : 'Exif', 0, 0
  ---------
  TIFF : // TIFF格式的EXIF数据
  ---------

JPEG APPn: FF En // APPn 标记,可选

DQT :0xFFDB  //Define Quantization Table,定义量化表


SOF0:0xFFC0  //Start of Frame,帧图像开始


DHT:0xFFC4  //Difine Huffman Table,定义哈夫曼表


SOS:0xFFDA  // Start of Scan,扫描开始 12字节


压缩数据


JPEG EOI : FF D9  //  图片结束

 

 

JPEG图片的标记

每一个JPEG文件的内容都开始于一个二进制的值 '0xFFD8', 并结束于二进制值'0xFFD9'。

在JPEG的数据中有好几种类似于二进制 0xFFXX 的数据, 它们都统称作 "标记", 代表了一段JPEG的 信息数据。

在JPEG 格式中, 最开始先是用一些标记来描述数据,然后是放置SOS数据流的起始(Startof Scan) 标记。在SOS标记的后面才是, 存放JPEG图像的数据流并终结于EOI标记。

 

0xFFD8 的意思是SOI图像起始(Start of image),0xFFD9 则表示 EOI图像结束 (End of image). 这两个特殊的标记的后面都不跟随数据, 而其他的标记在后面则会附带数据。标记的基本格式如下:

 

0xFF+标记号(1个字节)

数据长度(2个字节)(值为数据长度2字节+n字节)

数据内容(n个字节)

 

数据长度(2个字节) 是 "Motorola" 的字节顺序, 数据的低位被存放在高地址,也就是BigEndian。

 

数据长度为数据长度本身的2个字节,加数据内容的n个字节。不包含标记号的2个字节。如果下面的是一个标记的话:

FFC1 00 0C

它就表示这个标记(0xFFC1) 的数据占0x000C(等于12)个字节。'12' 包含了 "数据大小" 描述符, 也就是在0x000C后面只有10 个字节大小的数据。

 

JPEG文件中重要的标记
这里仅列出几个常用标记的标记代码、长度和表示的意义。

 

SOI,Start of Image,图像开始,2字节,固定值0xFFD8

 

JEPG APP0 应用程序保留标记0

 字段名称

字段长度

 Comments

标记代码 marker

2 bytes

固定值0xFF, 0xE0

数据长度 length

2 bytes

APP0总长度,不过括marker,但是包括length本身

标识符 identifier

5 bytes

固定的字符串"JFIF\0"

版本号 version

2 bytes

一般为0x0101或者0x0102,表示JFIF的版本号1.2

像素单位 unit

1 bytes

坐标单位,0没有单位; 1 pixel/inch2 pixel/cm

水平像素数目 Xdensity

2 bytes

 取值范围未知

垂直像素数目 YDensity

2 bytes

 取值范围未知

缩略图水平像素数目

1 byte

 取值范围未知

缩略图垂直像素数目

1 byte

 取值范围未知

缩略图RGB位图

3n bytes

n = Xthumbnail * Ythumbnail, 这是一个24bits/piexlRGB位图
如果没有微缩图像(这种情况更常见),则字段“缩略图水平像素数目”和字段“缩略图垂直像素数目”的值均为0。

 

APPn 应用程序保留标记

字段名称

字段长度

Comments

标记代码 marker

2 bytes

固定值0xFFE1 ~ 0xFFEF, n=1~15

数据长度 length

2 bytes

APPn的总长度,不包括marker2 bytes

详细信息

(length - 2) bytes

内容是应用特定的。
比如Exif使用APP1来存放图片的metadata
Adobe Photoshop
APP1APP13两个标记段分别存储了一副图像的副本。

 

DQT DefineQuantization Table

字段名称

子字段

字段长度

Comments

标记代码 marker

 

2 bytes

固定值0xFF, 0xDB

量化表长度 length

 

2 bytes

DQT的总长度,不包括marker2bytes

量化表

 

(length-2)bytes

 可以重复出现,表示多个量化表,但最多只能出现4次。

 

精度及量化表ID

1 bytes

4位:精度,只有两个可选值,08bits116bits
4位:量化表ID,取值范围为0~3

 

表项

(64*(精度+1)) bytes

 例如8位精度的量化表,其表项长度为64×(0+1)=64字节

 

JPEG Start ofFrame marker结构,帧图像开始

字段名称

长度

Comments

标记代码

2 bytes

固定值0xFFC0

数据长度

2 bytes

SOF marker长度,包括长度自身但不包含标记代码

精度

1 bytes

每个样本数据的位数,通常是8位,一般软件都不支持12位和16

图像高度

2 bytes

图像高度,单位:像素

图像宽度

2 bytes

图像宽度,单位:像素

颜色分量数

1 bytes

3个数值可选

1:灰度图;
3:YCrCb或YIQ;
4:CMYK
JFIF中使用YCrCb,故这里颜色分量数恒为3

颜色分量信息

颜色分量数x3

每个颜色分量:
1 byte
颜色分量ID
1 byte
水平/垂直采样因子。高4位:水平采样因子,低4位:垂直采样因子。
1 byte 当前分量使用的量化表ID

 



DHT,Difine HuffmanTable,定义哈夫曼表

字段名称

长度

Comments

标记代码

2 bytes

固定值0xFFC4

数据长度

2 bytes

包括长度自身但不包含标记代码

哈夫曼表

数据长度-2 bytes

出现1~4次。
例如,Adobe Photoshop 生成的JPEG图片文件中只有1个DHT标记段,里边包含了4个哈夫曼表;
Macromedia Fireworks生成的JPEG图片文件则有4个DHT标记段,每个DHT标记段只有一个哈夫曼表。

 

1 bytes

表ID和表类型
高4位:类型,只有两个值可选
0:DC直流;1:AC交流
低4位:哈夫曼表ID,
注意,DC表和AC表分开编码

 

16 bytes

不同位数的码字数量

 

16个不同位数的码字数量之和(字节)

编码内容

 

DRI,Define Restart Interval,定义差分编码累计复位的间隔

字段名称

长度

Comments

标记代码

2 bytes

固定值0xFFDD

数据长度

2 bytes

固定值0x0004

MCU块的单元中的重新开始间隔

2 bytes

设其值为n,则表示每n个MCU块就有一个RSTn标记。
第一个标记是RST0,第二个是RST1等,RST7后再从RST0重复。
如果没有本标记段,或间隔值为0时,就表示不存在重开始间隔和标记RST。

MCUMinimum Coded Unit,最小编码单元,通常是8x88x1616x16

 

JPEG  Startof Scan扫描开始

字段名成

长度

Comments

标记代码

2 bytes

固定值0xFFDA

数据长度

2 bytes

SOS长度,包括长度自身

颜色分量数

1 bytes

SOF中的字段值相同,即:
1:灰度图;
3: YCrCb或YIQ;
4:CMYK。
JFIF中使用YCrCb,故这里颜色分量数恒为3。

颜色分量信息

颜色分量数x3

每个样色分量:
1 byte
颜色分量ID
1 byte
直流/交流系数表号。高4位:直流分量使用的哈夫曼树编号;低4位:交流分量使用的哈夫曼树编号

压缩图像数据

3 bytes

 

 

1 byte

谱选择开始固定为0x00

 

1 byte

谱选择结束固定为0x3f

 

1 byte

谱选择 basic JPEG中总为00

 

SOS标记之后紧接着就是真正的图像信息了。图像信息直至遇到一个标记代码就自动结束,一般就是以EOI标记表示结束。

EOI,End of Image,图像结束。2字节。固定值0xFFD9。

补充说明一下,由于在JPEG文件中0xFF具有标志性的意思,所以在压缩数据流(真正的图像信息)中出现0xFF,就需要作特别处理。

具体方法是,在数据0xFF后添加一个没有意义的0x00。换句话说,如果在图像数据流中遇到0xFF,应该检测其紧接着的字符,如果是

1)0x00,则表示0xFF是图像流的组成部分,需要进行译码;

2)0xD9,则与0xFF组成标记EOI,则图像流结束,同时图像文件结束;

3)0xD0~0xD7,则组成RSTn标记,则要忽视整个RSTn标记,即不对当前0xFF和紧接的0xDn两个字节进行译码,并按RST标记的规则调整译码变量;

4)0xFF,则忽视当前0xFF,对后一个0xFF再作判断;

5)其他数值,则忽视当前0xFF,并保留紧接的此数值用于译码。

 

JPEG图片中的EXIF 数据

Exif- Exchange Image File Format,是Camera产业联合会发布的,主要目的就是设计一种文件格式,方便交换照片文件的metadata。

Exif使用 APP1(0xFFE1)标记来保存Exif数据,每一个 Exif 文件格式都开始于APP1标记。

 

Exif按照JPEG的规格在JPEG中插入一些 图像/数字相机 的信息数据以及缩略图像。于是你能通过与JPEG兼容的互联网浏览器/图片浏览器/图像处理等一些软件来查看Exif格式的图像文件,就跟浏览通常的JPEG图像文件一样。

Exif使用TIFF 格式来存储数据。下一篇详细讲解。

 

 

JPEG图片中的压缩图像数据

原始的图像数据量太大,于是几十年前一帮牛人想出来压缩图像数据的JPEG压缩标准。JPEG压缩时有损压缩,但是可以通过调整参数控制压缩率,已得到占空间较小的图片,同时将肉眼可分辨的损失降到最低。

JPEG压缩标准主要涉及到量化表(DQT)和哈夫曼表(DHT),这两种表作为压缩时的字典使用。压缩后的数据存储在SOS标记后。

JPEG压缩标准在下下篇讲解。

 

 

参考:

http://blog.youkuaiyun.com/kickxxx/article/details/8173332

http://www.cnblogs.com/leaven/archive/2010/04/06/1705846.html

http://stackoverflow.com/questions/8748671/jpeg-restart-markers



评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值