 JPG:為什么這個(gè)格式到處都打不開,以及瀏覽器能讀卻寫不了)
同事用 iPhone 拍了張現(xiàn)場(chǎng)照片發(fā)到群里我在 Windows 上雙擊打開系統(tǒng)提示需要安裝「HEIF 圖像擴(kuò)展」。裝完能看了但傳到公司系統(tǒng)里又報(bào)格式不支持。這事兒隔一段時(shí)間就會(huì)遇到一次。iPhone 從 iOS 11 起默認(rèn)就用這個(gè)格式拍照到現(xiàn)在快十年了兼容問題還是沒徹底解決。一、先分清兩件事容器和編碼大部分關(guān)于 HEIC 的困惑都源于把兩個(gè)概念混在了一起。HEIF 是容器格式High Efficiency Image File Format管的是文件怎么組織——一張圖、多張圖、縮略圖、深度圖、EXIF、編輯歷史都可以塞進(jìn)同一個(gè)文件。它本身不規(guī)定圖像數(shù)據(jù)用什么方式壓縮。HEVC 是編碼格式High Efficiency Video Coding也叫 H.265管的是像素怎么壓。我們平時(shí)說的 .heic 文件絕大多數(shù)是「HEIF 容器 HEVC 編碼」這個(gè)組合。蘋果給它起的名字叫 HEIC字母 C 就是 Coding 那個(gè) C。這個(gè)區(qū)分不是摳字眼。它直接解釋了后面所有的兼容性問題麻煩的不是容器是編碼。HEIF 容器只是個(gè)文件結(jié)構(gòu)誰都能實(shí)現(xiàn)HEVC 編碼背后是一整套專利池這才是卡住所有人的地方。順帶一提HEIF 容器里也可以放 AV1 編碼的數(shù)據(jù)那種叫 AVIF——同一個(gè)容器家族換了個(gè)不帶專利包袱的編碼器所以 AVIF 在瀏覽器里的支持速度比 HEIC 快得多。二、為什么各個(gè)平臺(tái)支持得七零八落環(huán)境讀 HEIC說明iOS 11 / macOS High Sierra原生支持蘋果自己推的格式Windows 10/11需裝擴(kuò)展「HEIF 圖像擴(kuò)展」免費(fèi)但依賴的「HEVC 視頻擴(kuò)展」要收費(fèi)Android9.0 起支持各廠商實(shí)現(xiàn)程度不一Safari 17原生支持Chrome / Firefox不支持至今沒有原生解碼大多數(shù)網(wǎng)站上傳不支持后端圖像庫(kù)要么沒編譯 HEVC要么不敢編Windows 那個(gè)坑最有代表性圖像擴(kuò)展是免費(fèi)的但它要調(diào)用 HEVC 解碼能力而「HEVC 視頻擴(kuò)展」在微軟商店里標(biāo)價(jià)幾塊錢。微軟不是想賺這幾塊錢是它得為每一份 HEVC 解碼器向?qū)@馗妒跈?quán)費(fèi)。 這就是問題的根源——HEVC 的專利授權(quán)是按份收費(fèi)的而且授權(quán)方不止一家。MPEG LA、Access Advance、Velos Media 各管一攤還有一批專利持有者誰都沒加入單獨(dú)找你談。一個(gè)瀏覽器廠商要原生支持 HEIC得先把這些賬算清楚。 對(duì)比一下 AV1那是一幫公司組了個(gè)開放媒體聯(lián)盟專門搞出來的免專利費(fèi)編碼所以 Chrome、Firefox 加 AVIF 支持的時(shí)候沒什么心理負(fù)擔(dān)。三、轉(zhuǎn)換的幾條路第一條用系統(tǒng)自帶的。 Mac 上預(yù)覽打開導(dǎo)出選 JPEG最省事。iPhone 上可以在「設(shè)置 → 相機(jī) → 格式」里改成「兼容性最好」以后直接拍 JPG——代價(jià)是文件大一倍左右。已經(jīng)拍好的照片通過「隔空投送」到 Mac 或者用微信發(fā)送時(shí)系統(tǒng)有時(shí)會(huì)自動(dòng)轉(zhuǎn) JPG但這個(gè)行為不穩(wěn)定別指望。 Windows 裝了 HEIF 擴(kuò)展之后畫圖打開另存為 JPG 也行就是批量處理很難受。第二條在線轉(zhuǎn)換工具。 搜出來一大堆大部分的工作方式是你把照片傳到它服務(wù)器它轉(zhuǎn)完給你下載。 這條路我個(gè)人不太用。手機(jī)相冊(cè)里的照片是最私人的東西之一傳到一個(gè)不知道誰在運(yùn)營(yíng)的服務(wù)器上刪沒刪、留沒留、有沒有被拿去訓(xùn)練模型都沒法驗(yàn)證。轉(zhuǎn)個(gè)格式而已不值得。第三條在瀏覽器本地轉(zhuǎn)。 這是這幾年才成立的方案。libheif 有 WebAssembly 版本把解碼器下載到瀏覽器里跑圖片本身一步都不用往外走。 判斷一個(gè)在線工具是不是真的本地處理有個(gè)很直接的辦法按 F12 打開 Network 面板轉(zhuǎn)一張圖看有沒有把圖片 POST 出去。真本地處理的話你只會(huì)看到 WASM 文件下載下來看不到圖片傳上去——這兩件事方向是相反的。四、轉(zhuǎn)成 JPG 會(huì)丟掉什么這一節(jié)很多轉(zhuǎn)換教程都不提但踩過一次就知道有多要命。 HEIC 不只是「一張壓得比較小的圖」它是個(gè)容器里面可能裝著好幾樣?xùn)|西。轉(zhuǎn)成 JPG 的時(shí)候JPG 裝不下的部分會(huì)被直接丟掉而且沒有任何提示。 Live Photo 的動(dòng)態(tài)部分。 iPhone 的實(shí)況照片實(shí)際是「一張 HEIC 一段 MOV 視頻」兩個(gè)文件靠元數(shù)據(jù)關(guān)聯(lián)。轉(zhuǎn) JPG 只處理靜態(tài)那一張視頻部分不會(huì)跟過去。想留住動(dòng)態(tài)效果得先在 iPhone 上把實(shí)況照片單獨(dú)存成視頻。人像照片里存著一張景深圖蘋果相冊(cè)的「調(diào)整景深」「換光效」全靠它。轉(zhuǎn) JPG 之后這張深度圖沒了虛化效果被永久烤進(jìn)像素里再也調(diào)不回來。 HDR 增益圖。 較新的 iPhone 拍的照片帶一張?jiān)鲆鎴D在支持 HDR 的屏幕上能顯示出更高的動(dòng)態(tài)范圍。轉(zhuǎn)成普通 JPG 后只剩基礎(chǔ)圖層在 HDR 屏上看會(huì)覺得「發(fā)灰、沒那么亮了」。 多幀數(shù)據(jù)。 連拍、HDR 合成這類照片容器里可能存著多張圖轉(zhuǎn)換工具通常只取主圖。 EXIF 大多能保留但看工具實(shí)現(xiàn)。要特別留意方向信息orientation——如果工具解碼時(shí)沒按 EXIF 把圖轉(zhuǎn)正、又沒把 orientation 字段帶過去你會(huì)得到一張?zhí)傻沟恼掌N易约耗沁叺奶幚硎墙獯a后按 EXIF 的 orientation 先把像素轉(zhuǎn)正再編碼所以方向不會(huì)出問題但深度圖、增益圖和 Live Photo 的視頻部分保不住。這不是某個(gè)工具偷懶凡是走「解碼成像素 → 重新編碼」這條路的都保不住——目標(biāo)格式里壓根沒有存放它們的地方。 所以一條實(shí)操建議重要的照片轉(zhuǎn)換之后別急著刪原圖。轉(zhuǎn)出來的 JPG 用于分發(fā)HEIC 原件自己留著。五、技術(shù)上最有意思的一點(diǎn)能讀寫不了我自己在做瀏覽器端的圖像處理HEIC 這塊折騰了不少時(shí)間結(jié)論是讀能做到純本地寫做不到。讀的路徑是通的。libheif 編譯成 WASM 大概幾百 KB按需加載解出來的像素直接進(jìn) canvas之后想轉(zhuǎn) JPG 轉(zhuǎn) WebP 都隨意。整個(gè)過程原圖不上傳。寫就是另一回事了兩個(gè)坎 第一個(gè)坎是專利。 前面說了HEVC 編碼授權(quán)是按份計(jì)費(fèi)的。一個(gè)免費(fèi)網(wǎng)頁(yè)工具用戶量上去之后這筆賬根本算不過來——而且授權(quán)方不止一家你還不知道到底該跟誰簽。 第二個(gè)坎是體積。 能用的 HEVC 編碼器比如 x265編譯成 WASM 之后體積很大為了一個(gè)使用頻率不高的輸出格式讓所有用戶先下載幾兆的編碼器這個(gè)成本收益完全不成正比。所以我這邊的處理是HEIC 讀走端側(cè)HEIC 寫走服務(wù)端界面上直接標(biāo)出來是哪一種不藏著。這個(gè)取舍不好看但比假裝能做要誠(chéng)實(shí)。 順便說一句絕大多數(shù)場(chǎng)景其實(shí)不需要寫 HEIC。你要 HEIC 干什么呢它的價(jià)值在于 iPhone 拍照時(shí)省空間而 iPhone 自己就會(huì)生成。反向把 JPG 轉(zhuǎn)成 HEIC除了滿足特定的歸檔要求日常幾乎用不上。六、幾條實(shí)操建議照片要發(fā)給別人、要上傳系統(tǒng)直接在 iPhone 設(shè)置里把格式改成「兼容性最好」一勞永逸省下所有后續(xù)折騰。存儲(chǔ)空間緊張的話再改回來。 已經(jīng)拍了一堆 HEIC批量轉(zhuǎn)的話Mac 用「預(yù)覽」全選導(dǎo)出最快Windows 建議找個(gè)支持批量的工具別一張張畫圖另存。 涉及隱私的照片證件、票據(jù)、合同拍照優(yōu)先選在瀏覽器里本地處理的工具轉(zhuǎn)完自己按 F12 驗(yàn)一下有沒有上傳。這個(gè)驗(yàn)證成本很低值得做一次。做開發(fā)的如果要在服務(wù)端處理 HEIC注意 ImageMagick 和 Pillow 默認(rèn)都不帶 HEVC 支持得自己編譯或者裝 pyheif、libheif 相關(guān)的綁定而且要留意你所在地區(qū)的專利合規(guī)問題——這塊比技術(shù)實(shí)現(xiàn)本身麻煩。我做的那個(gè)瀏覽器端圖像工具叫做圖映https://imging.cn所有功能幾乎都是源于身邊同事和朋友反饋的痛點(diǎn)HEIC 讀取用的就是上面說的 libheif WASM 方案按需加載轉(zhuǎn) JPG / WebP / PNG 全程在本地完成圖片不上傳HEIC 寫入受專利和體積限制走服務(wù)端界面會(huì)提前標(biāo)明。地址https://imging.cn如果你也在做類似的事容器和編碼這兩個(gè)概念一定要先分清楚能省掉很多繞路。