图片和图形之扩展色彩内容增强图形(20)

原文

概要


除了标准RGB(sRGB)之外,Android 8.0(API级别26)还引入了对额外色彩空间的色彩管理支持,以 在具有兼容显示的设备上呈现图形。有了这种支持,您的应用程序可以通过Java或本地代码来呈现通过PNG,JPEG和WebP文件加载的嵌入式宽色彩配置文件的位图。使用OpenGL或Vulkan的应用程序可以直接输出宽色域内容(使用Display P3和 scRGB)。此功能对于创建涉及高保真色彩再现的应用程序非常有用,例如图像和视频编辑应用程序。

了解宽色域模式


宽色彩配置文件是 ICC配置文件,如 Adobe RGB, Pro Photo RGB和 DCI-P3,它们可以表示比sRGB更广泛的颜色。支持宽色配置文件的屏幕可以显示深色原色(红色,绿色和蓝色)以及更丰富的次色(如洋红色,青色和×××)的图像。

在支持Android 8.0(API级别26)或更高级别的Android设备上,您的应用可以启用广色域色彩模式,以便系统识别并正确处理嵌入了宽色彩配置文件的位图图像。本 ColorSpace.Named类枚举Android支持常用的颜色空间的部分列表。

注意:启用宽色域模式后,活动窗口会使用更多的内存和GPU处理来进行画面构图。在启用宽色域模式之前,您应该仔细考虑该活动是否真正从中受益。例如,以全屏显示照片的活动很适合广泛的色域模式,但显示小缩略图的活动则不适用。

启用宽色域模式


使用该colorMode属性请求在兼容设备上以宽色域模式显示活动。在宽色域模式下,可以在sRGB色域外渲染窗口以显示更鲜艳的色彩。如果设备不支持广色域渲染,则此属性不起作用。如果您的应用需要确定给定的显示器是否具有宽色域功能,请调用该 isWideColorGamut()方法。您的应用程序也可以调用 isScreenWideColorGamut(),true 仅当显示器具有广泛的色域能力并且该设备支持广色域色彩渲染时才会返回。

显示器可能具有广泛的色域能力,但无法进行色彩管理,在这种情况下,系统不会授予应用广泛的色域模式。当显示器未经过颜色管理时(例如8.0之前的所有Android版本),系统都会将应用程序绘制的颜色重新映射到显示器的色域。

要在您的活动中启用宽色域,请将该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位长的值四个分量的滤色器,代替使用一个整数值的最常见表示。使用较长的值,可以比整数值更精确地定义颜色。如果您需要将颜色创建或编码为长整型值,请使用该类pack()中的其中一种方法Color。

您可以通过检查该getColorMode()方法是否返回 来验证您的应用是否正确请求了广色域模式COLOR_MODE_WIDE_COLOR_GAMUT(但此方法并未指示实际授予了广色域模式)。
图片和图形之扩展色彩内容增强图形(20)
图1.显示P3(橙色)与sRGB(白色)色彩空间

在本地代码中使用广泛的色域支持


本节介绍如何在OpenGL和 Vulkan API中启用宽色域模式( 如果您的应用程序使用本机代码)。

OpenGL的

为了在OpenGL中使用宽色域模式,您的应用程序必须包含具有以下扩展名之一的EGL 1.4库:

  • EGL_EXT_gl_colorspace_display_p3
  • EGL_EXT_gl_colorspace_scrgb
  • EGL_EXT_gl_colorspace_scrgb_linear

要启用此功能,您必须首先通过eglChooseConfig以下三种颜色缓冲区格式中的一种创建GL上下文 ,以在属性中实现宽色。宽色彩的颜色缓冲区格式必须是以下RGBA值集合之一:

  • 8,8,8,8
  • 10,10,10,2
  • FP16,FP16,FP16,FP16

然后,在创建渲染目标时请求P3色彩空间扩展,如以下代码片段所示:

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
}

以下代码片段显示了如何请求Vulkan交换链 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;
}

Lastest Update:2018.04.25

联系我

QQ:94297366

微信打赏:https://pan.baidu.com/s/1dSBXk3eFZu3mAMkw3xu9KQ

公众号推荐:

图片和图形之扩展色彩内容增强图形(20)

猜你喜欢

转载自blog.51cto.com/4789781/2120595
今日推荐