Android 8.0 (nivel de API 26) incorporó compatibilidad de administración de color para brindar espacios de color además de RGB estándar (sRGB) para renderizar gráficos en dispositivos con pantallas compatibles. Gracias a este apoyo, tu app puede renderizar mapas de bits con perfiles de amplia gama de colores incorporados que se cargan desde archivos PNG, JPEG y WebP mediante Java o código nativo. Las apps que usan OpenGL o Vulkan pueden generar directamente contenido con una amplia gama de colores (con Display P3 y scRGB). Esta función es útil para crear aplicaciones que implican la reproducción de color de alta fidelidad, como imágenes y videos de edición de fotos.
Cómo funciona el modo de amplia gama de colores
Los perfiles amplios de color perfiles de ICC, como Adobe RGB, . Foto RGB DCI‐P3, que son es capaz de representar un rango de colores más amplio que sRGB. Pantallas que admiten perfiles amplios de color pueden mostrar imágenes con colores primarios más profundos (rojos, verdes y azules), así como con colores colores (como magentas, cian y amarillos).
En los dispositivos Android que ejecutan Android 8.0 (nivel de API 26) o versiones posteriores compatibles, tu app puede
habilitar el modo de amplia gama de colores para una actividad mediante la cual el sistema reconoce y
procesar correctamente las imágenes de mapas de bits con perfiles amplios de color incorporados. El
La clase ColorSpace.Named
enumera una lista parcial de los recursos de uso común
los espacios de color compatibles con Android.
Nota: Cuando se habilita el modo de amplia gama de colores, el estado de la actividad usa más memoria y procesamiento de GPU para la composición de la pantalla. Antes de habilitar una amplia gama de colores debes considerar con cuidado si la actividad realmente se beneficia de él. Por ejemplo, un que muestra fotos en pantalla completa es una buena candidata para el modo de amplia gama de colores, pero pero no lo es una actividad que muestra miniaturas pequeñas.
Cómo habilitar el modo de amplia gama de colores
Usa el atributo colorMode
para solicitar que se muestre la actividad.
en el modo de amplia gama de colores
en dispositivos compatibles. En el modo de amplia gama de colores, una ventana puede representar
fuera del gamut sRGB para mostrar colores más vívidos. Si el dispositivo no admite la orientación ampliada, haz lo siguiente:
gamut, este atributo no tiene efecto. Si tu app necesita determinar si un determinado
pantalla admite una amplia gama de colores, llama al
isWideColorGamut()
. Tu app también puede llamar
isScreenWideColorGamut()
, que muestra true
solo si la pantalla admite una amplia gama de colores y el dispositivo admite una amplia gama de colores.
y la renderización de colores.
Una pantalla puede admitir una amplia gama de colores, pero no administrarla por color. En ese caso, la no otorgará a una aplicación el modo de amplia gama de colores. Cuando una pantalla no está administrada por color (como en todas las versiones de Android anteriores a la 8.0), el sistema reasigna la los colores que dibuja la app en la gama de la pantalla.
Para habilitar la amplia gama de colores en tu actividad, establece el colorMode
a wideColorGamut
en tu archivo AndroidManifest.xml
. Tú
deberás hacer esto para cada actividad para la que desees habilitar el modo de amplia gama de colores.
android:colorMode="wideColorGamut"
También puedes establecer el modo de color de manera programática en tu actividad llamando al
setColorMode(int)
y pasarlo
COLOR_MODE_WIDE_COLOR_GAMUT
Cómo procesar una amplia gama de colores
Para renderizar contenido con una amplia gama de colores, tu app debe cargar un mapa de bits de amplia gama de colores, es decir, un mapa de bits con un perfil de color que contiene un espacio de color más ancho que sRGB Los perfiles amplios comunes de color incluyen Adobe RGB, DCI-P3 y Display P3.
Tu app puede consultar el espacio de color de un mapa de bits llamando
getColorSpace()
Para determinar si el sistema reconoce un
un espacio de color específico para que sea de una amplia gama, puedes llamar
isWideGamut()
.
La clase Color
te permite representar un color con cuatro componentes.
empaquetado en un valor largo de 64 bits, en lugar de la representación más común que usa un número entero
valor. Con valores largos, puedes definir colores con
tienen más precisión
que los valores de números enteros. Si necesitas crear o codificar un color como valor largo, usa
uno de los métodos pack()
de la clase Color
Para comprobar si la app solicitó correctamente el modo de amplia gama de colores, comprueba que
el método getColorMode()
muestra
COLOR_MODE_WIDE_COLOR_GAMUT
(este método no indica que
sin embargo, si el modo de amplia gama de colores se otorgó realmente).
Cómo usar la compatibilidad con una amplia gama de colores en el código nativo
En esta sección, se describe cómo habilitar el modo de amplia gama de colores con OpenGL y APIs de Vulkan si tu app usa código nativo
OpenGL
Para usar el modo de amplia gama de colores en OpenGL, tu app debe incluir la biblioteca EGL 1.4 con una de las siguientes extensiones:
Para habilitar la función, primero debes crear un contexto de GL mediante
eglChooseConfig
, con uno de los tres admitidos
los formatos de búfer de color para una amplia gama de colores en los atributos. El formato del búfer de color para la
color debe ser uno de estos conjuntos de valores RGBA:
- 8, 8, 8, 8
- 10, 10, 10, 2
- FP16, FP16, FP16, FP16
Luego, solicita la extensión de espacio de color P3 cuando crees tu los destinos de renderización, como se muestra en el siguiente fragmento de código:
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
La compatibilidad de Vulkan con la amplia gama de colores se proporciona a través del
VK_EXT_swapchain_colorspace
.
Antes de habilitar la compatibilidad con la amplia gama de colores en tu código Vulkan, comprueba que el elemento
es compatible con
vkEnumerateInstanceExtensionProperties
Si la extensión está disponible, debes habilitarla durante
vkCreateInstance
antes de crear cualquier imagen de cadena de intercambio que
usa los espacios de color adicionales definidos por la extensión.
Antes de crear la cadena de intercambio, debes elegir el espacio de color deseado y, luego, hacer un bucle a lo largo de los plataformas físicas disponibles de los dispositivos y elige un formato de color válido para ellas espacio de color.
En dispositivos Android, Vulkan admite una amplia gama de colores con los siguientes espacios de color y
Formatos de color de VkSurfaceFormatKHR
:
- Espacios de color de la amplia gama de colores de Vulkan:
VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT
VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT
- Formatos de color Vulkan compatibles con una amplia gama de colores:
VK_FORMAT_R16G16B16A16_SFLOAT
VK_FORMAT_A2R10G10B10_UNORM_PACK32
VK_FORMAT_R8G8B8A8_UNORM
En el siguiente fragmento de código, se muestra cómo puedes verificar que el dispositivo sea compatible con Display P3. espacio de color:
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 }
En el siguiente fragmento de código, se muestra cómo solicitar una cadena de intercambio Vulkan con
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; }