多是目前最全面的中文介紹 😎
來自個人 blog HEIF & HEVC 研究 html
在升級 iOS 11 以後,iPhone 7 及更新的設備內的照片存儲將再也不用 JPEG 了,而採用了一種新的圖片格式 HEIF(發音同 heef),在 iOS 中對應的文件後綴爲 .heic ,其編碼用的是 HEVC(這個發不了音,哈哈哈)格式,又稱 H.265 (這個就很熟悉了 H.264 的下一代),同時視頻也用 HEVC 做爲編碼器,對應的文件後綴仍是 .mov 。android
這裏要注意他們倆的關係, HEIF 是圖片格式,而 HEVC 是編碼格式(相似 H.264,VP8),HEIF 是圖片容器(相似於視頻的 mkv,mp4 後綴),而用 HEVC 進行編碼的 HEIF 圖片就是後綴爲 .heic 的圖片,也是蘋果主要使用的格式。git
這兩個都是很新的標準,分別在 2015 和 2013 年才被 ISO 批准。這篇文章主要介紹一下 HEIF 格式和與其餘圖片格式相比的優劣。
發展史以下:
github
這張圖是 WWDC Session 511 的形容 Heif 的一句英文詩,JPEG 很大,可是 HEIF 和小。web
HEIF 全稱 High Efficiency Image Format (HEIF)。是由 Moving Picture Experts Group 制定的,存儲圖片和圖片序列的格式。
相關的介紹位置這邊能夠看到 nokiatech.github.io/heif/ ,對的,你沒有看錯,是 Nokia 的技術人員們制定的。相比 JPEG ,PNG 等傳統的圖片格式來講, HEIF 可算是至關年輕了,可是這種格式相比 JPEG 等有不少的優勢。json
支持存放多張圖片,相似相冊和集合。(實現多重曝光的效果)
瀏覽器
支持多張圖片實現 GIF 和 livePhoto 的動畫效果。緩存
在這個 Nokia 網站上能夠看到相關的例子。微信
在視頻文件中,容器和編碼是獨立開的,好比 mp4,mkv 等格式是容器,而 H.264,VP8 等是編碼。可是圖像文件中,像 JPEG 就是混合在一塊兒的(因此它很差用啊,哈哈哈哈),HEIF 就把容器和編碼分開了,有用來存放單個或者多個圖像的容器。markdown
因此基於不一樣的編碼器,會有不一樣的文件後綴。
編碼器 | 單文件後綴 | 連續圖片後綴 |
---|---|---|
HEVC | .HEIC | .HEICS |
H.264 | .AVCI | .AVCS |
Any codec | .HEIF | .HEIFS |
Apple 設備中默認使用的都是 HEVC 的編碼的 HEIF 格式。
在 Apple 所編碼的 HEIF 的文件組成大體以下圖,其 mdat - Media Data 中存放的是 exif 信息,縮略圖(320*240),和 HEVC 編碼後的圖片:
HEIF 底層是默認 tiled,就是片狀的有 512x512 個,由一個個小的圖塊,組成一張大圖,這一特性有以下的優勢:
HeifTile 和 SystemTile (CATiledLayer 等系統所提供的分塊加載)是不同的,可是二者結合會有很大的提高,因此在加載和處理特大圖片時,性能有大幅度的提高。
HEIF 所採用的熵編碼也和 JPEG 不同,JPEG 是用的霍夫曼編碼(Huffman),而 HEIF 使用的是基於上下文的自適應二進制算術編碼(CABAC),編碼的是數據量更小且更快。
每當一個新的技術推動至工業化,兼容性無疑是最重要的考量點。像 HEIF 這樣的圖片格式,並不像 JPEG / PNG 等已經被普遍應用和適配了,估計在 Apple 推出以前,大部分開發者和我同樣應該都是不知道的。目前工業化的體系內,對 HEIF 幾乎是不兼容,Windows 上沒法打開 HEIF 文件,10.13 前的 macOS 也沒法打開。蘋果在推行這一技術的時候,在內部也是作了不少兼容工做的。
通常狀況下,用戶是對這個格式無感知的,由於只有在新款支持硬解碼的 iOS 手機內部是以 heif & hevc 格式來存儲照片和視頻的,而在用戶經過 Airdrop 或者數據線傳送到電腦上的時候,對不兼容的設備會自動轉換到 JPEG 的格式。因此也不會影響你使用微信,微博等軟件。
不過在蘋果內部的 app 中,基本都已經用上了這一技術,如照片,FaceTime 等應用。意味着之後同等儲存空間能存放更多的照片和視頻,同時 FaceTime 也能節省更多了流量,相同網絡狀況下,FaceTime 也會更加清晰。
經過在 設置 -> 照片 選項中能夠設置傳到 MAC 或者 PC 上時保持 HEIF 格式。
HEIF 圖片:
編碼:
軟件:iOS11,運行 macOS 系統的 Mac 設備。
解碼:
硬件:A9 及以上芯片 iOS 設備(iPhone6s),配備 6 代及以上 Inter Core 處理(Skylake)。
HECV 視頻:
視頻分爲 8 位 / 10 位 兩種模式。
基本和圖片編解碼保持一致,惟一有區別的是 10 位硬解碼要求是 7 代 Intel 處理器。
總結一下,就是升到 iOS 11 以後,你的設備就能解析新格式的圖片和視頻,軟硬解碼的區別就是,硬解碼會更快並更省電。
對用戶的幾乎無感知切換的前提,確定是上層 API 沒有變化,調整的是最底層的 API,因此通常開發者使用上層的框架時,如 PhotoKIt 是不受影響的,不一樣格式的圖片都抽象爲了同一個對象。並且對圖片增長濾鏡和視頻的調整修改,最後都會渲染爲 JPEG 和 H.264。在這一級別的 API 是接觸不到圖片文件格式轉換所帶來的變化的。
Image I/O 中能夠直接讀寫 .heic 文件。
iOS 11 中 Image I/O 可以直接讀取 heif 的文件,包括讀取 exif,xmp 等信息。
let inputURL = URL(fileURLWithPath:Bundle.main.resourcePath! + "/IMG_0513.HEIC") let source = CGImageSourceCreateWithURL(inputURL as CFURL, nil) let image = CGImageSourceCreateImageAtIndex(source!, 0, nil) let options = [kCGImageSourceCreateThumbnailFromImageIfAbsent as String: true, kCGImageSourceThumbnailMaxPixelSize as String: 320] as [String: Any] let thumb = CGImageSourceCreateThumbnailAtIndex(source!, 0, options as CFDictionary) guard let cImage = image else { print("not support heic") return; }複製代碼
固然也能夠選擇把 CGImage 寫入到 HEIC 格式,雖然這樣能夠節約更多的存儲空間,實際使用的時候仍是要注意轉換操做。
let url = URL(fileURLWithPath: "/tmp/output.heic") guard let destination = CGImageDestinationCreateWithURL(url as CFURL,AVFileType.heic as CFString, 1, nil) else{ fatalError("unable to create CGImageDestination") } CGImageDestinationAddImage(imageDestination, image, nil) CGImageDestinationFinalize(imageDestination)複製代碼
Apple 提供的不少 API ,供開發者檢測設備是否支持新的格式。提供了兩種推薦的工做場景事例。
社交網絡
在社交軟件中,涉及到圖片分享之類的內容,是沒法肯定接受者是否能支持新的格式的, Apple 的策略是建議都進行轉換到 JPEG 的操做,好比發送郵件,或者經過 extension 分享的時候,傳入其餘 app 中的時候,都已經進行了轉換了。
p2p 場景
在該場景中,設備和設備間的直接鏈接,首先把接受者的支持格式告知發送者,而後發送者根據兼容的狀況,選擇 HEIF 或者 JPEG。好比 AirDrop 。
同時諸如 SDWebImage 目前也正在作對 heif 的兼容。
大部分的播放器已經支持了 HEVC 即 H.265 的編碼器,可是針對 HEIF 的圖片兼容性仍是相對較差的。
目前有的是 Nokia 提供了一個 C++ 的讀寫庫,經過該庫,支持把 HEIF 的圖片的解碼到 HEVC 的編碼數據。
Android 兼容性:
依賴 Nokia 的庫,目前只能經過 CPU 軟解。
聽說 LG 正在研發支持硬解的手機。(raddit)
網頁兼容性:
Nokia 提供 JS 庫。
Windows 兼容性:
目前也沒有能直接打開 HEIF 文件的應用。
經常拿來與 HEVC 來作對比的是 VP9。二者的性能相近,可是 VP9 是開源的,而 HEVC 是須要專利費的( $2 每設備)。
目前暫時沒有經過 VP9 進行編碼的圖片,因此這裏主要對比的是 webp 就是經過 VP8 進行編碼的圖片。
webp
WebP目前支持桌面上的Chrome和Opera瀏覽器,手機支持僅限於原生的Android瀏覽器、Android系統上的Chrome瀏覽器、Opera Mini瀏覽器。
下面是幾個關鍵技術點的對比,可見 HEIF 功能是最強大的。
.heic | WebP | JPEG | |
---|---|---|---|
最大尺寸 | 無上限 | 16383x16383 | 65535x65535 |
編碼 | HEVC | VP8 | JPEG |
是否支持其餘編碼 | YES | NO | NO |
支持音頻/文字 | YES | NO | NO |
支持多圖片 | YES | YES | NO |
支持裁剪 | YES | NO | NO |
支持透明 | YES | YES | NO |
支持縮略圖 | YES | NO | YES |
分塊加載 | YES | NO | NO |
下面的數據均是官方提出:
Webp 同等質量下,比 JPEG 圖像小 25-34%。
JPEG 平均須要比 HEVC 多 139% 的比特率,意味着同等質量下,JPEG 的大小是 HEVC 的 2.39 倍!
把兩個的參考標準統一一下:
Webp 比 JPEG 小 25-34%
HEVC 比 JPEG 小 58%
可是在我本身的本地的測試中,測試了五組圖片。webp 以 80 的質量進行壓縮,hevc 以 crf 18 (視覺無損)壓縮,同時增長一個 320x240 的縮略圖。
本身進行 HEIF 轉碼的流程是,將圖片經過 ffmpeg 編碼到 H.265,再經過 Nokia 的庫轉成 HEIC 文件(Heif)。
//生成主圖像編碼 ffmpeg -i $1 -crf 18 -preset slower -pix_fmt yuv420p -f hevc bitstream.265 //生成縮略圖編碼 ffmpeg -i $1 -vf scale=320:240 -crf 28 -preset slower -pix_fmt yuv420p -f hevc bitstream.thumb.265 //調用 Nokia 的工具 ./writerapp config.json複製代碼
格式 | heic | webp | |
---|---|---|---|
JPEG 4352x3264 | 5.7 MB | 487 KB | 538 KB |
JPEG 8688x5792 | 34.7 MB | 3.5 MB | 2.7 mb |
tiff 3840x2160 | 1.8 MB | 238 KB | 264 KB |
PNG 1243x2208 | 1.5 MB | 175 KB | 209 KB |
PNG 512x512 | 243 KB | 13 KB | 14 KB |
除了一組特大圖的表現不同外,其餘幾組圖片相比, heif 確實比 webp 壓縮效率高 10-20%。
畢竟和 HEVC 對標的技術應該是 VP9,因此 heif 可以領先也是情理之中。
主要測試設備是 iPhone 6s Plus 系統 iOS 11,用的解碼方法 webp 爲 Google 提供的庫,hevc 和 jpeg 用的是 CGImageSource 來解碼。
測試用圖片仍是以前的五組圖片,同時對 JPEG 進行了一些壓縮,測試了 5 組平均值(去一個最高,去一個最低),估計加載的時候存在緩存,因此第一次讀圖片數據的時候耗時較大。
第一組用第一張 7.7 mb 的 jpeg 壓縮後大小 1.1mb
jpeg 7.43 2.77 1.46 1.9 2.14 2.00 【佔用率 6 %】
hevc 41.0 3.45 3.35 2.62 2.92 2.66 【佔用率 6 %】
webp 216.6 216.8 217.5 261.9 195.2 【佔用率 21 %】
格式 | 平均時間 | 佔用率 |
---|---|---|
jpeg | 2.20ms | 5 % |
hevc | 3.01ms | 6 % |
webp | 220.1ms | 20% |
第二組用第三張 1.8 mb 的 tff,轉換成 jpeg 以後大小爲 815 KB。
hevc 58.4 3.1 2.8 1.13 2.65 2.82 2.02 【 2% 】
jpeg 65.3 2.67 2.76 2.73 2.69 2.87 1.34 【 2% 】
webp 130.2 110.9 117.5 114.8 120.9 112.8 124.84 【 12% 】
格式 | 平均時間 | 佔用率 |
---|---|---|
jpeg | 2.73ms | 2 % |
hevc | 2.68ms | 2 % |
webp | 115.58ms | 12% |
第三組用的最後一張 243KB PNG ,轉換成 JPEG 以後大小爲 43 KB。
hevc 47 3.24 2.7 3.21 2.63 1.74 【 1 %】
jpeg 16 6.70 6.97 4.46 7.2 6.76 7.08 【 1% 】
webp 20.7 20.2 12.5 22.0 19.3 19.4 【 2 % 】
格式 | 平均時間 | 佔用率 |
---|---|---|
jpeg | 6.90ms | 1 % |
hevc | 2.95ms | 1 % |
webp | 20.1ms | 2 % |
測試結果因爲硬解碼的支持,jpeg 和 hevc 解碼速度和 CPU 佔用率都比 webp 快和小不少,jpeg 和 hevc 不相伯仲,可見蘋果內部對其優化也至關到位,才把它放到 iOS 11 中。
相比 JPEG 來比很強大,畢竟是下一代技術,可是兼容性可想而知,在「最大效率」和「最大兼容」二者中間仍是要根據使用場景進行權衡,目前的優點也只有最新的 iPhone 能體驗到,但不久的未來可能全部的手機都去支持照片深度,動態照片,更廣的色域等。HEVC 也許和推行 H.264 同樣,逐漸成爲了工業界的標準,但又可能和推行 acc 的處境同樣,只是成爲了蘋果的標準而已,終究仍是要看市場的反應了。