JPEG/Exif/TIFF格式解讀(1):JEPG圖片壓縮與存儲原理分析


JPEG文件簡介

JPEG的全稱是JointPhotographicExpertsGroup(聯合圖像專家小組),它是一種常用的圖像存儲格式, jpg/jpeg是24位的圖像文件格式,也是一種高效率的壓縮格式,文件格式是JPEG(聯合圖像專家組)標准的產物,該圖像壓縮標准是國際電信聯盟(International Telecommunication Union,ITU)、國際標准化組織(International Organization for Standardization,ISO)和國際電工委員會(International Electrotechnical Commission,IEC)共同制定。JPEG標准正式地稱為ISO/IEC IS(國際標准)10918-1:連續色調靜態圖像數字壓縮和編碼(Digital Compression and Coding of Continuous-tone Still Images)和ITU-T建議T.81。

JPEG是第一個國際圖像壓縮標准,用於連續色調靜態圖像(即包括灰度圖像和彩色圖像),其最初目的是使用64Kbps的通信線路傳輸720×576 分辨率壓縮后的圖像。通過損失極少的分辨率,可以將圖像所需存儲量減少至原大小的10%。由於其高效的壓縮效率和標准化要求,目前已廣泛用於彩色傳真、靜止圖像、電話會議、印刷及新聞圖片的傳送上。但那些被刪除的資料無法在解壓時還原,所以* .jpg/.jpeg文件並不適合放大觀看,輸出成印刷品時品質也會受到影響。

JPEG文件格式

JPEG的文件格式一般有兩種文件擴展名:.jpg和.jpeg,這兩種擴展名的實質是相同的,我們可以把.jpg的文件改名為.jpeg,而對文件本身不會有任何影響。嚴格來講,JPEG的文件擴展名應該為.jpeg,由於DOS時代的8.3文件名命名原則,就使用了.jpg的擴展名,這種情況類似於.htm和.html的區別。

JPEG標准不指定任何固有的文件格式。它只定義壓縮比特流的語法。這就產生了一定數量的文件格式來存儲JPEG壓縮后的圖像,例如JPEG文件交換格式(JPEG File Interchange Format,JFIF),JPEG推廣到TIFF6.0、FlashPix等。但它們中的每一個都不能認為是由國際標准委員會支持的正式定義的國際標准。

JPEG格式可以分為標准JPEG漸進式JPEGJPEG2000三種格式。

標准JPEG:該類型的圖片文件,在網絡上應用較多,只有圖片完全被加載和讀取完畢之后,才能看到圖片的全貌;它是一種很靈活的圖片壓縮方式,用戶可以在壓縮比和圖片品質之間進行權衡。不過,通常來講,其壓縮比在10:1到40:1之間,壓縮比越大,品質就越差,壓縮比越小,品質就越好。JPEG格式壓縮的主要是高頻信息,對色彩的信息保留較好,適合應用於互聯網,可減少圖像的傳輸時間,可以支持24bit真彩色,也普遍應用於需要連續色調的圖像。JPEG由於可以提供有損壓縮,因此壓縮比可以達到其他傳統壓縮算法無法比擬的程度。其壓縮模式有以下幾種:

  1. 順序式編碼(SequentialEncoding)

  2. 遞增式編碼(ProgressiveEncoding)

  3. 無失真編碼(LosslessEncoding)

  4. 階梯式編碼(HierarchicalEncoding)

JPEG的壓縮步驟

  1. 顏色轉換:由於JPEG只支持YUV顏色模式,而不支持RGB顏色模式,所以在將彩色圖像進行壓縮之前,必須先對顏色模式進據轉換。轉換完成之后還需要進行數據采樣。一般采用的采樣比例是2:1:1或4:2:2。由於在執行了此項工作之后,每兩行數據只保留一行,因此,采樣后圖像數據量將壓縮為原來的一半。

  2. DCT變換:DCT(DiscreteConsineTransform)是將圖像信號在頻率域上進行變換,分離出高頻和低頻信息的處理過程。然后再對圖像的高頻部分(即圖像細節)進行壓縮,以達到壓縮圖像數據的目的。首先將圖像划分為多個8*8的矩陣。然后對每一個矩陣作DCT變換(變換公式此略)。變換后得到一個頻率系數矩陣,其中的頻率系數都是浮點數。

  3. 量化:由於在后面編碼過程中使用的碼本都是整數,因此需要對變換后的頻率系數進行量化,將之轉換為整數。由於進行數據量化后,矩陣中的數據都是近似值,和原始圖像數據之間有了差異,這一差異是造成圖像壓縮后失真的主要原因。

  4. 編碼:編碼采用兩種機制:一是0值的行程長度編碼;二是熵編碼(EntropyCoding)。在JPEG中,采用曲徊序列,即以矩陣對角線的法線方向作“之”字排列矩陣中的元素。這樣做的優點是使得靠近矩陣左上角、值比較大的元素排列在行程的前面,而行程的后面所排列的矩陣元素基本上為0值。行程長度編碼是非常簡單和常用的編碼方式,在此不再贅述。編碼實際上是一種基於統計特性的編碼方法。在JPEG中允許采用HUFFMAN編碼或者算術編碼。

更詳細可以參看《色彩空間RGB/CMYK/HSL/HSB/HSV/Lab/YUV基礎理論及轉換方法:RGB與YUV》、《視頻采樣,量化,編碼,壓縮,解碼相關技術原理學習筆記 》

Baseline JPEG/基本JPEG:這種類型的JPEG文件存儲方式是按從上到下的掃描方式,把每一行順序的保存在JPEG文件中。打開這個文件顯示它的內容時,數據將按照存儲時的順序從上到下一行一行的被顯示出來,直到所有的數據都被讀完,就完成了整張圖片的顯示。這種圖片在web中,如果沒有給圖片指定寬高,會造成重繪。

progressive jpeg/漸進式JPEG:JPEG文件包含多次掃描,這些掃描順尋的存儲在JPEG文件中。打開文件過程中,會先顯示整個圖片的模糊輪廓,隨着掃描次數的增加,圖片變得越來越清晰。該類型的圖片是對標准JPEG格式的改進,當在網頁上下載漸進式JPEG圖片時,首先呈現圖片的大概外貌,然后再逐漸呈現具體的細節部分,因而被稱之為漸進式JPEG。這種通過HTTP2 多路復用傳遞漸進式JPEG的掃描圖層來提高感知性能和速度指數的方式已經早在2012年被Google的John Mellor 注意到了。他一直在實驗SPDY協議,HTTP2的前身。

JPEG2000:一種全新的圖片壓縮發,壓縮品質更好,並且改善了無線傳輸時,因信號不穩定而造成的馬賽克及位置錯亂等問題。另外,作為JPEG的升級版,JPEG2000的壓縮率比標准JPEG高約30%,同時支持有損壓縮和無損壓縮。它還支持漸進式傳輸,即,先傳輸圖片的粗略輪廓,然后,逐步傳輸細節數據,使得圖片由模糊到清晰逐步顯示。此外,JPEG2000還支持感興趣區域,也就是說,可以指定圖片上感興趣區域的壓縮質量,還可以選擇指定的部分先進行解壓。還有個優勢就是,JPEG2000從無損壓縮到有損壓縮可以兼容

jpeg2000編碼解碼模塊與過程

jpeg編碼解碼系統構成

 

 

壓縮步驟

由於JPEG的有損壓縮方式(Lossy mode of operation)並不比其他的壓縮方法更優秀,

因此我們着重來看它的有損壓縮中最常用的基線JPEG算法(baseline sequential)。以一幅24位彩色圖像為例,JPEG的壓縮步驟分為:

顏色轉換

JPEG支持圖像采用任何一個色彩空間,支持1~4個顏色分量。灰度圖像顏色分量數為1。RGB、YUV、YCbCr等擁有3種顏色分量。4種顏色分量的例子是青、洋紅、黃和黑(Cyan,Magenta,Yellow,and Black,CMYK)。為了減少色度通道包含的大量的冗余信息,本例中采用YCbCr色彩空間。首先需要進行從RGB到YCbCr的色彩空間變換:

  • Y = 0.299000R + 0.587000G + 0.114000B

  • Cb = -0.168736R - 0.331264G + 0.500002B

  • Cr = 0.500000R - 0.418688G - 0.081312B

其中,Y表示亮度分量,Cb和Cr表示藍紅色度分量。

DC電平偏移

最初,在圖像中的像素存儲在無符號的整數中。對於數學計算,在圖像中任何變換或數學計算開始之前,根本上是將這些采樣轉換成兩個補碼表示。DC電平偏移的目的是保證輸入圖像的采樣有近似地集中在零附近的動態范圍。DC電平偏移執行的圖像采樣只通過無符號數表示。

方法:假設圖片分量的采樣精度為n,那么分量中的每個像素值應減去2的(n-1)次冪。

對於圖像而言他的采樣由無符號的整數表示,例如CT(X光斷層成像)圖像,動態范圍已經集中於零附近,所以不需要DC電平偏移。

子采樣

色彩空間轉換之后,圖像的大多數空間信息包含在亮度分量Y中。色度分量Cb和Cr包含大量冗余的顏色信息,所以我們運用子采樣較少色度數據量以在丟失少量信息的情況下壓縮圖像。基線JPEG常用的子采樣格式為4:2:0,同時支持4:2:2和4:4:4顏色格式。

DCT變換

DCT(DiscreteCosineTransform)是將圖像信號在頻率域上進行變換,分離出高頻和低頻信息的處理過程。然后再對圖像的高頻部分(即圖像細節)進行壓縮,以達到壓縮圖像數據的目的。首先將圖像划分為多個8*8的矩陣。然后對每一個矩陣作DCT變換。變換后得到一個頻率系數矩陣,其中的頻率系數都是浮點數。

量化

由於在后面編碼過程中使用的碼本都是整數,因此需要對變換后的頻率系數進行量化,將之轉換為整數。由於進行數據量化后,矩陣中的數據都是近似值,和原始圖像數據之間有了差異,這一差異是造成圖像壓縮后失真的主要原因。

在這一過程中,質量因子的選取至為重要。值選得過大,可以大幅度提高壓縮比,但是圖像質量就比較差;反之,質量因子越小(最小為1),圖像重建質量越好,但是壓縮比越低。對此,ISO已經制定了一組供JPEG代碼實現者使用的標准量化值。

右圖的兩個量化表的設計是根據由Lohscheller做的心理視覺實驗來確定二維基函數的可見閾值。

編碼

從前面過程我們可以看到,顏色轉換完成到編碼之前,圖像並沒有得到進一步的壓縮,DCT變換和量化可以說是為編碼階段做准備。

編碼采用兩種機制:一是0值的行程長度編碼;二是熵編碼(EntropyCoding)。

之字形排序(Zig-zag ordering)

在JPEG中,采用曲徊序列,即以矩陣對角線的法線方向作“之”字排列矩陣中的元素。這樣做的優點是使得靠近矩陣左上角、值比較大的元素排列在行程的前面,而行程的后面所排列的矩陣元素基本上為0值。

使用RLE對交流系數(AC)進行編碼

  • 行程長度編碼是非常簡單和常用的編碼方式,在此不再贅述。

    需要注意的是,AC系數的之字形序列編碼中有兩個特殊符號——(0,0)和(15,0)。第一個特殊符號指的是塊的結束(end-of-block,EOB),用來表明在之字形塊中剩余的元素都是零。另一個特殊符號是指零游程長度(zero-run-length,ZRL),用來表明16個零游程。基線JPEG允許的零游程最大長度是16個。如果這里的零超過16個,那么這個游程分成幾個長度為16的零游程。

  • 使用DPCM對直流系數(DC)進行編碼

    DCT系數量化之后,通過差分編碼對量化后的DC系數編碼。當前塊的DC系數減去前個塊的DC系數,然后對其差值進行編碼,如右圖所示。這就利用了鄰接塊DC值之間的空間相關性。

  • 熵編碼:編碼實際上是一種基於統計特性的編碼方法。在JPEG中允許采用HUFFMAN編碼或者算術編碼。而基線JPEG算法(baseline sequential)采用的是前者。

    經過RLE編碼的AC系數可以映射成兩個標志(RUNLENGTH,CATEGORY)和(AMPLITUDE),前者采用的是霍夫曼編碼,而后者采用的是VLI編碼。同理經過DPCM編碼的DC系數同樣可以映射成兩個標志(CATEGORY)和(AMPLITUDE),前者采用霍夫曼編碼,后者采用VLI編碼。

    基線JPEG允許使用4個霍夫曼表,兩個用於AC系數編碼,兩個用於DC系數編碼。

 

 

如何識別JEPG文件的

 

其實很簡單,就是判斷前面3個字節是什么,如果發現是FF D8 FF開始,那就認為它是JEPG圖片。

JPG文件是由一段段的數據構成的組成的(segment),段的多少和長度並不是一定的。只要包含了足夠的信息,該JPEG文件就能夠被打開。

JPEG格式和標記

JPEG圖片格式組成部分:SOI(文件頭)+APP0(圖像識別信息)+ DQT(定義量化表)+ SOF0(圖像基本信息)+ DHT(定義Huffman表) + DRI(定義重新開始間隔)+ SOS(掃描行開始)+ EOI(文件尾)

003yXckxzy7poBkOYsf57&690.jpeg

以16進制模式打開JPG文件,就會發現

JPEG 文件中有一些形如 0xFF** 這樣的數據,它們被稱為“標志(Marker)”,它表示 JPEG 信息數據段。例如 0xFFD8 代表 SOI(Start of image), 0xFFD9 代表 EOI(End of image)。

標志 0xFFE0~0xFFEF 被稱為 "Application Marker",它們不是解碼 JPEG 文件必須的,可以被用來存儲配置信息等。EXIF 也是利用這個標志段來插入信息的,具體來說,是 APP1(0xFFE1) Marker。所有的 EXIF 信息都存儲在該數據段。

------------------
名稱  標記碼  說明
------------------
SOI   D8     文件頭
EOI   D9     文件尾
SOF0  C0     幀開始(標准 JPEG)
SOF1  C1     同上
DHT   C4     定義 Huffman 表(霍夫曼表)
SOS   DA     掃描行開始
DQT   DB     定義量化表
DRI   DD     定義重新開始間隔
APP0  E0     定義交換格式和圖像識別信息
DNL   DC     標記碼
COM   FE     注釋

段類型有30種,但只有10種是必須被所有程序識別的,其它的類型都可以忽略。

JPEG format and Marker

SOI Marker Marker XX size=SSSS Marker YY size=TTTT SOS Marker size=UUUU Image stream EOI Marker
FFD8 FFXX SSSS DDDD...... FFYY TTTT DDDD...... FFDA UUUU DDDD.... I I I I.... FFD9

0xFFE0~0xFFEF之間的標記被叫做 "應用標記", 它們在JPEG圖像解碼中不是必須存在的. 它們被使用於用戶的應用程序之中. 例如, 老款的olympus/canon/casio/agfa 數字相機使用 JFIF(JPEG文件交換格式/JPEG File Interchange Format)來存儲圖像. JFIF 使用 APP0(0xFFE0) 標記來插入數字相機的配置信息數據和縮略圖.

Exif也使用應用標記來插入數據, 但是Exif 使用 APP1(0xFFE1)標記來避免與JFIF格式的 沖突. 且每一個 Exif 文件格式都開始於它, 如

SOI 標記 標記 XX 的大小=SSSS 標記 YY 的大小=TTTT SOS 標記 的大小=UUUU 圖像數據流 EOI 標記
FFD8 FFXXlo0p SSSS DDDD...... FFYY TTTT DDDD...... FFDA UUUU DDDD.... I I I I.... FFD9

Exif也使用應用標記來插入數據, 但是Exif 使用 APP1(0xFFE1)標記來避免與JFIF格式的 沖突. 且每一個 Exif 文件格式都開始於它, 如;

Marker used by Exif

0xFF+Marker Number(1 byte)+Data size(2 bytes)+Data(n bytes)

SOI Marker APP1 Marker APP1 Data Other Marker
FFD8 FFE1 SSSS 457869660000 TTTT...... FFXX SSSS DDDD......

該圖像文件從SOI(0xFFD8) 標記開始, 因此它是一個 JPEG 文件. 后面馬上跟着 APP1 標記. 而它的所有 Exif數據都被存儲在 APP1 數據域中. 上面的 "SSSS" 這部分表示 APP1 數據域 (Exif data area)的大小. 請注意這里的大小 "SSSS" 包含描述符本身的大小.

在 "SSSS"后面, 是 APP1 的數據. 其中第一個部分是一個特殊的數據,它用來標識是否是 Exif, 其值是ASCII 字符 "Exif" 和 兩個0x00字節 的組合字符串.

在 APP1 標記域的后面是, 跟隨着其他的 JPEG 標記

exif數據解析

如果圖片圖片是16進制數據,如下:

FF D8  FF E0 00 10 4A 46 49 46 00 01 02 01 00 60 00 60   00 00  FF E1 08 32 45 78 69 66 00 00 49 49 10 60 00 60   20 00 …… FFD9  

那么FF D8為SOI標志位,FF E0為exif文件起始位,后面四位 為exif marker信息的長度。取這個長度的數據解析為TIFFdata數據,exif直接解析為字符串貌似也沒有問題。 

FF D8 

    FF E0 00 10 4A 46 49 46 00 01 02 01 00 60 00 60   00 00        mark0,00 10 =16位

    FF E1 08 32 45 78 69 66 00 00 49 49 10 60 00 60   20 00 …… mark1,00 10 =2098位 

    …… 

   Image stream

FFD9

jpeg二進制代碼源碼分析 

每個段都是由FFxx開頭,其中xx是段的標識,接着就是就是兩位的端長度。后面跟着的就是數據。前面的元數據外讀取完成后,后面的二進制數據就是圖片數據。

數據大小描述符(2個字節) 是 "Motorola" 的字節順序, 數據的低位被存放在高地址,也就是 BigEndian. 請注意上面中的 "數據內容" 中包含他前面的數據大小描述符, 如果下面的是一個標記的話;

這個長度的表示方法是按照高位在前,低位在后的,與 Intel 的表示方法不同。比方說一個段的長度是0x12AB,那么它會按照0x12,0xAB的順序存儲。但是如果按照Intel的方式:高位在后,低位在前的方式會存儲成0xAB,0x12,而這樣的存儲方法對於JPEG是不對的。這樣的話如果一個程序不認識JPEG文件某個段,它就可以讀取后兩個字節,得到這個段的長度,並跳過忽略它。

關於exif信息解碼,請閱讀《JPEG/Exif/TIFF格式解讀(2):圖片元數據保存及EXIF詳解

jpeg10中必須的段類型

這里列舉10種必備的段類型

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 Forma的縮寫,即JPEG文件交換格式,另外還有TIFF等格式,很少用

  • “如果有RGB縮略圖就=16+3n”是什么意思呢?比如說“縮略圖X像素”和“縮略圖Y像素”的值均為48,就表示有一個48×48像素的縮略圖(n=48×48),縮略圖是24位真彩位圖,用3個字節來表示一個像素,所以共占用3n個字節。但大多數JPG文件都沒有這個“雞肋”縮略圖。

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, 每個都有自己的信息字節

 

 

 

 

 

 

 

 

參考資料:

圖片文件Exif信息詳細說明 blog.sina.com.cn/s/blog_651251e60102uz3d.html#AboutExif

圖像Exif信息 元數據(Metadata) https://www.jianshu.com/p/a6d67df60e7e

關於圖片文件旋轉JPEG與EXIF信息  https://blog.csdn.net/yulimin/article/details/102827865

https://www.media.mit.edu/pia/Research/deepview/exif.html

https://baike.baidu.com/item/Exif/422825?fr=aladdin

讀取JPG圖片的Exif屬性(一) - Exif信息簡介 https://blog.csdn.net/fioletfly/article/details/53605959

讀取JPG圖片的Exif屬性(二) - C代碼實現 https://blog.csdn.net/fioletfly/article/details/54094940

讀取JPG圖片的Exif屬性(三) - Exif屬性讀取GPS信息代碼(C/C++實現)https://blog.csdn.net/fioletfly/article/details/54133422

在jpg圖片添加Exif信息的C程序實現 https://blog.csdn.net/psy6653/article/details/79658144

JPEG添加EXIF https://blog.csdn.net/weixin_43549602/article/details/84654965

jpeg圖片格式詳解 https://blog.csdn.net/yun_hen/article/details/78135122

壓縮算法——JPEG2000 編解碼原理 https://blog.csdn.net/ytang_/article/details/76571635

PNG、JPEG、BMP等幾種圖片格式詳解 https://www.jianshu.com/p/f5557c0e689e

使用HTTP2和漸進式JPEG圖片更快的加載圖像 https://www.zcfy.cc/article/performance-calendar-raquo-even-faster-images-using-http2-and-progressive-jpegs-2216.html

 

 

轉載本站文章《JPEG/Exif/TIFF格式解讀(1):JEPG圖片壓縮與存儲原理分析》,
請注明出處:https://www.zhoulujun.cn/html/theory/multimedia/CG-CV-IP/8396.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM