JPEG图片格式介绍
对于摄像头采集的图像一般为YUV居多,这对于jepg就非常的友好,因为jpeg图像也是使用yuv形式进行编码的。这篇我们来学习下jpg图像的编码格式。
1. JPEG格式文件简介
JPEG(Joint Photographic Experts Group,联合图像专家小组),是一种常用的图像存储格式, jpg/jpeg是24位的图像文件格式,也是一种高效率的压缩格式,是面向连续色调静止图像的一种压缩标准。同样一幅画面,用.jpg/.jpeg格式储存的文件是其他类型图形文件的1 /10~1/20。一般情况下,.jpg/.jpeg文件只有几十KB,而色彩数最高却可达到24位,所以它被广泛运用在Internet上,以节约宝贵的网络传输资源。
1.1 拓展名.jpg与.jpeg
JPEG的文件格式一般有两种文件扩展名:.jpg和.jpeg,这两种扩展名的实质是相同的,我们可以把.jpg的文件改名为.jpeg,而对文件本身不会有任何影响。严格来讲,JPEG的文件扩展名应该为.jpeg,由于DOS时代的8.3文件名命名原则,就使用了.jpg的扩展名,这种情况类似于.htm和.html的区别。
1.2 JPEG的三种格式
JPEG格式可以分为:标准JPEG、渐进式JPEG 和 JPEG2000三种格式。
该类型的图片文件,在网络上应用较多,只有图片完全被加载和读取完毕之后,才能看到图片的全貌;它是一种很灵活的图片压缩方式,用户可以在压缩比和图片品质之间进行权衡。不过通常来讲,其压缩比在10:1到40:1之间,压缩比越大,品质就越差,压缩比越小,品质就越好。
该类型的图片是对标准JPEG格式的改进,当在网页上下载渐进式JPEG图片时,首先呈现图片的大概外貌,然后再逐渐呈现具体的细节部分,因而被称之为渐进式JPEG。
一种全新的图片压缩发,压缩品质更好,并且改善了无线传输时,因信号不稳定而造成的马赛克及位置错乱等问题。另外,作为JPEG的升级版,JPEG2000的压缩率比标准JPEG高约30%,同时支持有损压缩和无损压缩。它还支持渐进式传输,即先传输图片的粗略轮廓,然后,逐步传输细节数据,使得图片由模糊到清晰逐步显示。
2. JPEG文件结构详解
2.1 JPEG图片格式组成部分
JPEG格式的文件是分为一个一个的段来存储的,段的多少和长度并不是一定的。只要包含了足够的信息,该JPEG文件就能够被打开,呈现给人们。但JPEG文件的每个段都一定包含两部分:
1. 段的标识与类型。它由两个字节构成:第一个字节是段标识0xFF,第二个字节是段类型(对于不同的段是不同的),具体如以下表:
<pre class="md-fences md-end-block ty-contain-cm modeLoaded mCustomScrollbar _mCS_2 mCS-autoHide mCS_no_scrollbar" id="pre-4pntFm"><div id="mCSB_2" class="mCustomScrollBox mCS-minimal-dark mCSB_vertical_horizontal mCSB_outside" tabindex="0"><div id="mCSB_2_container" class="mCSB_container mCS_y_hidden mCS_no_scrollbar_y mCS_x_hidden mCS_no_scrollbar_x" dir="ltr"><code-pre class="code-pre" id="pre-mQWEyp"><span>段类型 表示符号 说明<br/><span>——————————————————————————————————<br/><span>SOI D8 文件头<br/><span><span><br/><span>APP0 E0 定义交换格式和图像识别信息<br/><span>APP1 E1<span class="cm-tab"> <span class="cm-tab"> <span class="cm-tab"> 同上<br/><span>.... .... .... <br/><span>APPn En<span class="cm-tab"> <span class="cm-tab"> <span class="cm-tab"> 同上<br/><span><span><br/><span>DQT DB 定义量化表<br/><span><span><br/><span>SOF0 C0 图像基本信息<br/><span>SOF1 C1 同上<br/><span>.... .... ....<br/><span>SOFn Cn 同上<br/><span><span><br/><span>DHT C4 定义 Huffman 表(霍夫曼表)<br/><span>DRI DD 定义重新开始间隔<br/><span>SOS DA 扫描行开始<br/><span>COM FE 注释<br/><span>EOI D9 文件尾<br/><span>......</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code-pre></div></div></pre>
2. 段的长度。紧接着的两个字节存放的是这个段的长度(除了前面的两个字节0xFF和0xXX,X表示不确定。他们是不算到段的长度中的)。其作用是这样的话如果一个程序不认识JPEG文件某个段,它就可以读取后两个字节,得到这个段的长度,并跳过忽略它。
注意:这个长度的表示方法并不是按照传统intel的方法(低位在前,高位在后,即逆序),而是按照高位在前,低位在后的。比方说一个段的长度是0x12AB,那么它会按照0x12,0xAB的顺序存储。但是如果按照Intel的方式:高位在后,低位在前的方式会存储成0xAB,0x12,而这样的存储方法对于JPEG是不对的。
综上,以下是jpeg图片的段的一般结构:
<pre class="md-fences md-end-block ty-contain-cm modeLoaded mCustomScrollbar _mCS_3 mCS-autoHide mCS_no_scrollbar" id="pre-mwK2NC"><div id="mCSB_3" class="mCustomScrollBox mCS-minimal-dark mCSB_vertical_horizontal mCSB_outside" tabindex="0"><div id="mCSB_3_container" class="mCSB_container mCS_y_hidden mCS_no_scrollbar_y mCS_x_hidden mCS_no_scrollbar_x" dir="ltr"><code-pre class="code-pre" id="pre-TMZsyZ"><span><span class="cm-operator">-----------------------------------------------------------------<br/><span><span class="cm-variable">名称 <span class="cm-variable">字节数 <span class="cm-variable">数据 <span class="cm-variable">说明<br/><span><span class="cm-operator">-----------------------------------------------------------------<br/><span><span class="cm-variable">段标识 <span class="cm-number">1 <span class="cm-variable">FF <span class="cm-variable">每个新段的开始标识<br/><span><span class="cm-variable">段类型 <span class="cm-number">1 <span class="cm-variable">段类型编码(称作“标记码”)<br/><span><span class="cm-variable">段长度 <span class="cm-number">2 <span class="cm-variable">包括段内容和段长度本身,<span class="cm-variable">不包括段标识和段类型<br/><span><span class="cm-variable">段内容 <span class="cm-variable">≤65533字节 </span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code-pre></div></div></pre>
注意:
- 有些段没有长度描述也没有内容,只有段标识和段类型。文件头和文件尾均属于这种段。
- 段与段之间无论有多少FF都是合法的,这些FF称为“填充字节”,必须被忽略掉。
2.2 段类型
段类型有30种,以下列出几种必须的或常见的 JPEG文件段类型。
- SOI(必须):SOI段定义了文件头。该段仅有两个字节:FF D8,这两个字节代表了JPEG文件的开始。
- APP0, APP1, APP2....(必须):APP0段定义了交换格式和图像识别信息。包含了一些像素和略缩图相关的信息。
- DQT(必须):DQT段定义了量化表。JPEG文件一般有两个DQT段,为亮度定义1个, 为色度定义1个。
- SOF0, SOF1, SOF2....(必须):SOF段定义了图像基本信息。包含了一些图片长宽高、组件等信息。
- DHT(必须) :DHT段定义了Huffman表,即霍夫曼编码表。
- DRI(非必须**):DRI段定义了重新开始间隔,很多JPEG文件没有这个段。**
- SOS(必须):SOS段定义了扫描行开始,紧接着SOS段后的就是一个个扫描行(压缩的图像数据)。
- COM(非必须**):COM段定义了注释段,有的JPEG文件没有这个段。**
- EOI(必须):EOI段定义了文件尾,该段仅有两个字节:FF D9,这两个字节代表了JPEG文件的结束。