Android 8.0 (API 級別 26) 推出了色彩管理支援功能,可為 多色空間 在具有相容顯示器的裝置上呈現圖形的標準 RGB (sRGB)。有了這項支援服務 您的應用程式可以透過從 PNG、JPEG 和 WebP 檔案載入的嵌入式廣色設定檔,來算繪點陣圖 透過 Java 或原生程式碼使用 OpenGL 或 Vulkan 的應用程式可以直接輸出廣色域內容 (使用 Display P3 和 scRGB)。這項能力 適用於建立需要高保真色彩複製的應用程式,例如圖片和影片 編輯應用程式。
瞭解廣色域模式
廣色域有 ICC 設定檔,例如 Adobe RGB、 專業相片 RGB DCI-P3,也就是 能夠呈現比 sRGB 更多的色彩範圍。支援廣色設定檔的螢幕 可顯示深層主色 (紅色、綠色和藍色) 的圖片,以及更豐富的次要顏色 顏色 (例如洋紅色、青色和黃色)。
在支援 Android 8.0 (API 級別 26) 以上版本的 Android 裝置上,應用程式可以
針對系統辨識且
能正確處理含內嵌廣色設定檔的點陣圖圖片。
ColorSpace.Named
類別列舉一部分的常用
Android 支援的色域
注意:啟用廣色域模式時,活動的 會耗用較多記憶體和 GPU 處理螢幕組成畫面。啟用廣色域前 模式,應審慎考量活動是否真的有益。舉例來說 以全螢幕顯示相片的活動是廣色域模式的理想選擇 顯示小型縮圖的活動則不屬於。
啟用廣色域模式
使用 colorMode
屬性要求顯示的活動
在相容裝置上支援廣色域模式。在廣色域模式下,視窗可
在 sRGB 色域之外,顯示更加鮮豔的色彩。如果裝置不支援廣色
銀河算繪,這個屬性不會有任何作用。如果應用程式需要判斷
螢幕是廣色域功能
isWideColorGamut()
方法。你也可以呼叫
isScreenWideColorGamut()
,會傳回 true
只有在螢幕支援廣色域且裝置支援廣色域時
以及顏色呈現方式
螢幕可能是廣色可變色,但無法管理顏色。在這種情況下, 系統將不會授予應用程式廣色域模式。如果螢幕未採用顏色管理 - 就像所有 Android 8.0 之前版本一樣,系統會重新對應 應用程式繪製的色彩。
如要在活動中啟用廣色域,請設定 colorMode
屬性設為 wideColorGamut
。AndroidManifest.xml
個人中心
請找出要啟用廣色模式的每個活動。
android:colorMode="wideColorGamut"
您也可以呼叫
setColorMode(int)
方法並傳入
COLOR_MODE_WIDE_COLOR_GAMUT
。
算繪廣色域內容
如要算繪廣色域的內容,應用程式必須載入寬色點陣圖, 包含大於 sRGB 色彩空間的色彩設定檔。常見的廣角色彩描述檔包括 Adobe RGB、DCI-P3 和 Display P3。
應用程式可以呼叫
getColorSpace()
。判斷系統能否辨識
才能達到廣角
isWideGamut()
方法。
Color
類別可讓您使用四個元件表示顏色
包裝成 64 位元長值,而非使用整數的最常見表示
值。您可以使用長值定義顏色
精確度大於整數值如果您需要建立或編碼長值的顏色,請使用
Color
類別中的其中一個 pack()
方法。
您可以檢查應用程式是否正確要求廣色域模式,方法是檢查
getColorMode()
方法會傳回
COLOR_MODE_WIDE_COLOR_GAMUT
(這個方法不會指出
但卻表示實際上是否授予廣色域模式)。
在原生程式碼中使用廣色域支援功能
本節說明如何使用 OpenGL 和 Vulkan API (如果應用程式使用原生程式碼)。
OpenGL
如要在 OpenGL 使用廣色域模式,應用程式必須加入 EGL 1.4 程式庫,內含: 下列任一副檔名:
如要啟用這項功能,您必須先透過
eglChooseConfig
,包含支援的其中一種
屬性中的廣色顏色緩衝區格式。寬度的顏色緩衝區格式
顏色必須是下列其中一個 RGBA 值組:
- 8、8、8、8
- 10、10、10、2
- FP16、FP16、FP16、FP16
然後在建立 顯示目標,如以下程式碼片段所示:
std::vector<EGLint> attributes; attributes.push_back(EGL_GL_COLORSPACE_KHR); attributes.push_back(EGL_GL_COLORSPACE_DISPLAY_P3_EXT); attributes.push_back(EGL_NONE); engine->surface_ = eglCreateWindowSurface( engine->display_, config, engine->app->window, attributes.data());
Vulkan
對於廣色域的 Vulkan 支援是透過
VK_EXT_swapchain_colorspace
。
在 Vulkan 程式碼中啟用廣色支援前,請先檢查
擴充功能是透過
vkEnumerateInstanceExtensionProperties
。
如果可以使用擴充功能,請務必在更新期間啟用
請vkCreateInstance
,再建立任何交換鏈映像檔
使用擴充功能定義的額外色彩空間。
建立交換鏈之前,您需要選擇偏好的色域,然後繞行 可用的實體裝置介面,並為該元件選擇有效的顏色格式 色彩空間。
在 Android 裝置上,Vulkan 支援下列色域和下列色域:
VkSurfaceFormatKHR
種顏色格式:
- Vulkan 廣色域色空間:
VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT
VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT
- 支援廣色域的 Vulkan 色彩格式:
VK_FORMAT_R16G16B16A16_SFLOAT
VK_FORMAT_A2R10G10B10_UNORM_PACK32
VK_FORMAT_R8G8B8A8_UNORM
下列程式碼片段說明如何檢查裝置是否支援 Display P3 色域:
uint32_t formatCount = 0; vkGetPhysicalDeviceSurfaceFormatsKHR( vkPhysicalDev, vkSurface, &formatCount, nullptr); VkSurfaceFormatKHR *formats = new VkSurfaceFormatKHR[formatCount]; vkGetPhysicalDeviceSurfaceFormatsKHR( vkPhysicalDev, vkSurface, &formatCount, formats); uint32_t displayP3Index = formatCount; for (uint32_t idx = 0; idx < formatCount; idx++) { if (formats[idx].format == requiredSwapChainFmt && formats[idx].colorSpace==VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT) { displayP3Index = idx; break; } } if (displayP3Index == formatCount) { // Display P3 is not supported on the platform // choose other format }
下列程式碼片段說明如何透過
VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT
:
uint32_t queueFamily = 0; VkSwapchainCreateInfoKHR swapchainCreate { .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, .pNext = nullptr, .surface = AndroidVkSurface_, .minImageCount = surfaceCapabilities.minImageCount, .imageFormat = requiredSwapChainFmt, .imageColorSpace = VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT, .imageExtent = surfaceCapabilities.currentExtent, .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, .preTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR, .imageArrayLayers = 1, .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE, .queueFamilyIndexCount = 1, .pQueueFamilyIndices = &queueFamily, .presentMode = VK_PRESENT_MODE_FIFO_KHR, .oldSwapchain = VK_NULL_HANDLE, .clipped = VK_FALSE, }; VkRresult status = vkCreateSwapchainKHR( vkDevice, &swapchainCreate, nullptr, &vkSwapchain); if (status != VK_SUCCESS) { // Display P3 is not supported return false; }