Instagram 如何在新 iPhone 的廣色域屏幕中顯示廣色域圖像

簡評:去年九月,蘋果發布了 iPhone 7 和 iPhone 7 plus,在新品上搭配了能顯示更寬色彩範圍的 Wide Color 廣色域屏幕。Instagram 團隊剛剛完成廣色域屏幕的適配,這篇文章將分享應用程序轉換適配的過程,以幫助其他開發者也能做到同樣的事情。精準的顏色顯示意味著我們能看到最真實的色彩,設計師或許只需要關注屏幕的色彩校準,而開發者更應該關注代碼的底層實現,尤其是圖片類應用程序的開發者。

為什麼選用廣色域

在此之前,大多數捕獲的照片都是 sRGB 色域。由於 sRGB 色域與大多數顯示器能很好地兼容,因此它也成為網路上共享圖像的標準。雖然 sRGB 在大多數時候都能很好地表現顯示器的色彩,但是隨著顯示器和相機技術的提高,sRGB 開始顯現它的不足。

先看下圖這張照片,

當使用 iPhone 7 Plus 拍攝時,房間中大多數色塊都在 sRGB 色域之外,除非採用更寬的色彩空間,否則會造成細節丟失。蘋果為其新 iPhone 選擇的色彩空間是 P3,下圖中以藍色顯示的部分是在 sRGB 顯示範圍之外但是是存在於 P3 以內的:

接下來我們將介紹在 Instagram 代碼中會改變的內容,以便為廣色域提供顏色支持。

A Canary

在處理廣域色彩兼容性時最有用的工具是「金絲雀圖像(Canary)」。這種圖像只有在廣域色彩範圍時才會顯示。這裡是我們的示例。

如果你看到的只是一個紅色方塊,那說明你的顯示器只能顯示 sRGB 色域。如果在廣域顯示器上打開,你會看到 Instagram logo 的出現。所以這就是一種圖像信息丟失。

你可以使用它來確定在哪個過程中你的應用程序丟失了顏色信息。

捕獲

這是比較簡單的部分。從 iOS10 開始,Apple 的 API 將從兼容的相機中輸出廣色域圖像。我們做的一個調整是轉換為新的 AVCaptureDeviceDiscoverySession,這讓我們能充分利用 iPhone 7 Plus 的雙鏡頭系統。

Core Graphics 操作

獲取圖像後,會做些簡單處理。其中大部分都是在做 Core Graphics,所以有一些變化以適配廣色域。

如果你曾經做過 Core Graphics,你可能知道這個:

UIGraphicsBeginImageContextWithOptions(...)n//你的繪圖操作這裡nUIImage * image = UIGraphicsGetImageFromCurrentImageContext(); nUIGraphicsEndImageContext();n

作為一個傳統的API,它不是廣色域的。因此,我們將採用這個:UIGraphicsImageRenderer:

UIGraphicsImageRendererFormat * format = [[UIGraphicsImageRendererFormat alloc] init]; nformat.prefersExtendedRange = YES; nUIGraphicsImageRenderer * renderer = [[UIGraphicsImageRenderer alloc] initWithSize:size format:format]; nUIImage * image = [renderer imageWithActions:^(UIGraphicsImageRendererContext * rendererContext){ n //這裡的繪圖操作n}];n

我們為了簡化 IG 的轉換,做的是創建一個包裝類 UIGraphicsImageRenderer,它接受一個 CGContext 的圖像繪製操作。工程師可以使用 [UIImage renderedImageWithSize:(CGSize) actions:(ImageActionsBlock)actions],而 ImageActionsBlock 單個參數是一個 CGContextRef。在 iOS10 上它使用新的渲染器,調用 imageWithActions。

創建色彩空間

在其他地方,通常 CGColorSpaceCreateDeviceRGB 在創建時使用 CGColorSpaceRef。這將在大多數設備上創建 sRGB 顏色空間,我們會失去 sRGB 以外的色彩。

我們可以先看看設備屏幕是否支持廣色域顯示(使用UIScreen.mainScreen.traitCollection.displayGamut),如果是,請使用CGColorSpaceCreateWithName(kCGColorSpaceDisplayP3)。

當我們下載圖片但不確定要使用什麼顏色空間時,我們改用它 CGImageGetColorSpace,因此,一旦我們向 iOS 應用程序提供顯示 P3 圖片,我們只在需要時創建廣色域的信息。

濾鏡

Instagram 使用 OpenGL 進行圖像編輯。OpenGL 不是顏色管理;它在一個範圍(例如,0.0 到 1.0)上操作,並且它決定映射的顏色。適配的過程中,最大的變化是確保當我們從 GL 表面提取像素緩衝區時,我們使用適當的顏色空間,然後從 a CVPixelBufferRef 轉換為 a CGImageRef。

圖像輸出

在這一點上,我們捕獲了一個廣色域圖像,在 CoreGraphics 中調整它的大小,並把它通過 OpenGL,保持廣色域的顏色信息。最後一步是用 UIImage 把它變成 JPEG。可以用 UIImages 在 Photoshop 中載入導出的圖像(Xcode 的調試器集成,以便在預覽中打開),並檢查生成的圖像的顏色配置文件和其他顏色信息。

圖像存儲

一旦圖像生成,我們做一些最後的調整,然後在 Python 使用 Pillow。最後通過 Facebook 的 CDN 在全球提供圖像。

現在的問題在於大多數用戶目前的設備都不是兼容廣色域的,因此這些設備也沒有良好的顏色管理。所以在多個顏色配置文件之間轉換圖像會增加我們的複雜性。

為了保持簡單,我們選擇了在後端存儲兩個版本,一個廣色域和一個非廣版本,並使用 Python ImagesCms 庫進行轉換(這裡是一個方便的教程)。

#ICC_PROFILES是表示磁碟上的文件路徑的字元串converted_image n= ImageCms.profileToProfile(image, n DISPLAY_P3_ICC_PROFILE,n SRGB_ICC_PROFILE)n

在讀取時,我們的應用程序先判斷是否為廣色域圖像,並且後端以合適的配置文件動態地提供圖像。在將來,當大多數圖像都是廣色域,同時大多數顯示器都具備色彩管理時,我們可能會重新寫入演算法。

原文:Bringing Wide Color to Instagram

相關閱讀:

  • Instagram的新衣:看Instagram首席設計師怎樣做設計

  • UI 設計中顏色使用法則

  • Python 的學習階段

歡迎關註:知乎專欄「極光日報」,每天為 Makers 導讀三篇優質英文文章。


推薦閱讀:

SODO學堂 獨家教程 | 壓印戒指金工技法
比有錢買房更牛逼的是,你有一個好的裝修品位…
與其發一萬句我愛你,不如跟這些情話十級的大師取取經

TAG:设计 | Instagram | iOS |