ByteScope

HEIC 檔案格式

High Efficiency Image Container,iOS 11 以後 Apple 的預設照片格式。

MIME 類型
image/heic
副檔名
.heic
分類
圖片

Magic number(檔案簽章)

0x0000000466747970ftypISO-BMFF 'ftyp' box
0x0000000868656963heicbrand 'heic'

關於 HEIC 格式

HEIC 把 HEVC 壓縮過的靜態影像包在 HEIF 容器裡,讓照片大小比 JPEG 減少約一半。它是 ISO-BMFF 檔案,'ftyp' 品牌識別為 'heic'。不過從 iPhone 傳出來的東西很少只有一張圖:同一個檔案裡通常還帶著縮圖、深度圖、HDR 增益圖,以及未經修改的原始影像加上一份非破壞性的編輯清單,全部各自是一個 item,由檔案前段的 'meta' box 建立索引。這才是它跟 JPEG 真正的差別 — 一個 HEIC 是一個小型的影像資料庫,檢視器顯示哪一張,取決於它認定哪個 item 是主要的。

檔頭結構,一個位元組一個位元組看

位移長度欄位意義
04ftyp box size檔案類型 box 的長度,大端序;有一個主要品牌識別加兩個相容品牌識別時是二十四。ISO-BMFF 的整數全部是大端序。特殊值在整個容器裡到處都一樣:1 代表類型後面跟著 64 位元的大小,0 代表這個 box 一路延伸到檔案結尾。
44Box type66 74 79 70。檔案類型 box 必須排第一,所以這四個位元組是整個格式裡唯一真正固定的位置,而它和 AVIF、HEIF、MP4、MOV、3GP 完全共用、分不出彼此。
84Major brand68 65 69 63 代表單張、以 HEVC Main profile 編碼的靜態影像。相關的品牌識別涵蓋各種變體:heix 是 Main 10 與更高的 profile,hevc 和 hevx 是影像序列,heim、heis、hevm、hevs 則是多視角。它們全都是 HEVC,講話的時候也全都被叫做 HEIC。
124Minor version純資訊用,慣例是 00 00 00 00。它不是品牌識別的修訂版本,讀取端也不可以因為這裡出現意外的值就拒收檔案。
16variableCompatible brands一串四位元組的品牌識別,把 box 剩下的空間填滿。macOS 寫 heic 和 mif1;iPhone 通常寫 mif1、heic、miaf,再加上 MiHB 或 MiHE 這類編碼限制品牌識別。讀取端只要認得其中任何一個就可以打開檔案 — 這正是為什麼這裡出現 mif1 並不會讓這個檔案變成 HEIF。
244Next box size24 位元組的 ftyp 之後,接著的不管是什麼 box,這就是它的標頭。走訪 box 的方式就是把每個大小加到目前位移上,沒有別的索引,也沒有重新同步的辦法,所以一個長度寫錯,後面的東西全部賠進去。
284Next box type幾乎一律是 6D 65 74 61 — meta。裡面的 pitm box 指名主要 item,iinf 列出每個 item 和它的類型,iloc 給出每個 item 的位元組範圍,iprp 則放它們的屬性,包括尺寸與旋轉。檢視器要決定顯示什麼,需要的東西全都住在那裡。

怎麼跟長得像的格式分開

容易搞混的怎麼分
AVIF到位移 7 為止一個位元組都不差,接著位移 8 是 68 65 69 63 對上 61 76 69 66。結構上它們是同一個容器、同一套 meta 與 item 機制;差別在 item 資料是被哪個編碼壓的,HEVC 還是 AV1。這個區別決定了檔案在哪裡打得開:HEIC 需要 HEVC 解碼器和專利授權,AVIF 不用,而除了 Safari 之外沒有瀏覽器畫得出 HEIC。
HEIF又是位移 8 的主要品牌識別:heic 明確主張裡面的 item 是 HEVC,而 mif1 是不綁編碼的品牌識別,只主張這個檔案遵循影像檔結構。幾乎每個 HEIC 都會把 mif1 也列進相容品牌識別,所以在整個 box 裡任意比對 mif1 是經典的偵測器 bug,會把 HEIC 檔案通通報成一般的 HEIF。
QuickTime MovieLive Photo 是成對出現的 — 一張 .heic 靜態圖配一段 .mov 影片,兩者帶著同一個內容識別碼 — 而且開頭都是一個 box 大小接著 ftyp。位移 8 的品牌識別分得開它們:heic 對上 qt,而且 MOV 帶的是裝著樣本的 trak box,HEIC 帶的是 meta box 裡的 item。只複製了一半,就是 Live Photo 那麼常變成一張普通靜態圖的原因。
JPEG位移 0 的 FF D8 FF 對上一個通常是 00 00 00 18 的 box 長度。決定用哪一種的相機設定只有一個開關:「高效率」拍出 HEIC,「最相容」拍出 JPEG;而且 Apple 的傳輸路徑在把照片送到 Windows 機器時還會順手把 HEIC 轉成 JPEG — 所以同一張照片到底以哪種格式抵達,要看它是怎麼被複製過來的。

常見的壞法

  • 少了 HEVC 解碼器,被誤當成檔案壞掉。Windows 要另外裝一個編碼擴充功能才打得開 HEIC,而多數瀏覽器永遠不會支援。一個在 Apple 硬體以外的地方到處報錯的檔案,幾乎都是完好的:動手修之前,先確認位移 4 讀到 ftyp、位移 8 讀到 heic。
  • 截斷。meta box 坐在檔案前段,所以尺寸、方向和 item 清單都活著,缺的只有影像資料。各家檢視器的反應不一致 — 有些會顯示內嵌的縮圖,那是另一個小得多的獨立 item,於是給人一種檔案沒事的錯覺,直到你把它放大到原尺寸為止。
  • 顯示錯 item。一個 HEIC 裡有好幾張影像,由 pitm box 指名主要的那一張。無視 pitm、直接解碼第一個找到的 item 的軟體,可能秀出深度圖、縮圖或未編輯的原始影像,而不是使用者預期的那張照片 — 看起來像檔案壞了,其實是讀取端的 bug。
  • 轉檔時把編輯弄丟。iOS 是以非破壞性的方式存調整參數的:一個輔助 item 加上原封不動的原始影像。所以轉檔工具若只把主要 item 抽出來卻沒套用那些調整,產出的檔案在技術上完全正確,秀的卻是所有編輯之前的樣子。而且沒有任何東西會提醒你這件事發生了。
  • box 大小和它的內容對不起來。因為走訪整棵 box 樹靠的就是一連串指標加法,一個長度錯了,剖析器就會把某段酬載當成 box 標頭讀,然後放棄整個檔案剩下的部分。它報出來的錯誤,通常指的是離真正損壞處很遠的某個 box。

這個格式現在還在用嗎

從 2017 年的 iOS 11 起,HEIC 就是每一支 iPhone 的預設拍攝格式,之後許多 Android 旗艦機也跟進,所以以產量算,它是地球上被製造得最多的影像格式之一 — 儘管幾乎沒有人拿它發佈。同畫質下它大約是 JPEG 的一半大,而且帶得動 JPEG 結構上根本裝不下的東西:10 位元深度、alpha 通道、人像模式散景用的深度圖、連拍與 Live Photo 序列、HDR 增益圖,還有非破壞性的編輯歷史。擋住它成為網路格式的是授權。HEVC 的專利分散在多個持有者組成的專利池裡,瀏覽器廠商拒絕內建解碼器,至今也只有 Safari 畫得出來 — 而 AVIF 就是為了補這個缺口而生的:同樣的容器,換上免權利金的編碼。實務上的定位是:HEIC 是拍攝與保存用的格式,這兩件事它都做得很好,而任何要離開 Apple 生態系的東西都得轉檔 — 要最大相容性就轉 JPEG,要上網就轉 AVIF 或 WebP。Apple 相機那個「最相容」設定的存在,就是為了讓一開始就不想碰這件事的人不必轉檔。

在這個站上打開 HEIC 檔

這些全部在你的瀏覽器裡跑,檔案不會離開你的電腦。

相關格式

容易和 HEIC 搞混的格式,可以比對它們的開頭位元組。

格式開頭位元組副檔名
HEIF66 74 79 70.heif
AVIF66 74 79 70.avif
JPEGFF D8 FF.jpg
MP466 74 79 70.mp4

常見問題

檔案的 magic number 是什麼?

檔案開頭的前幾個位元組,不管檔名寫什麼,它標明的是真正的格式。PNG 一定以 89 50 4E 47 開頭,ZIP 則是 50 4B 03 04。作業系統、瀏覽器和 file 指令讀的都是這幾個位元組,而不是相信副檔名 — 這就是為什麼把檔案改名並不會改變它實際上是什麼。

我要怎麼自己檢查 magic number?

在 macOS 或 Linux 上,xxd -l 16 檔名 會印出前 16 個位元組;在 Windows 上,PowerShell 的 Format-Hex -Path 檔名 -Count 16。或者把檔案丟進本站的檔案類型辨識工具,它會在本機讀取位元組並告訴你是什麼格式,不會上傳任何東西。

為什麼兩種格式的 magic number 會一樣?

因為其中一種是建立在另一種之上。docx、xlsx、pptx、apk、jar 與 epub 骨子裡都是 ZIP 壓縮檔,所以全都以 ZIP 的簽章開頭;要分辨它們得看裡面的項目。Java class 檔和 macOS 的通用二進位檔都以 CA FE BA BE 開頭,靠緊接其後的欄位區分。

有完全沒有 magic number 的檔案嗎?

有。XML、HTML、JSON、SVG、CSV 這類以文字為基礎的格式沒有固定的位元組簽章,所以改用結構來辨識:開頭的 <?xml 宣告、<svg 元素,或是 { 後面接著帶引號的鍵。這種偵測是合理推測而非確定,因此本參考頁會把這些格式標示為結構偵測。

magic number 相符就代表檔案安全嗎?

不代表。它告訴你的是格式,不是內容是否無害 — 一個貨真價實的 PDF 或 docx 仍然可能夾帶惡意內容。辨識真實類型是有用的第一道檢查,尤其在副檔名和位元組不一致的時候,但它不是惡意軟體掃描。

手上有檔案可能是 HEIC?用檔案類型辨識工具查出來 — 它在本機讀取 magic number,不上傳任何東西。或者瀏覽所有格式。