Android 8.0 (niveau d'API 26) offre la prise en charge de la gestion des couleurs pour des espaces de couleur, et le standard RVB (sRVB) pour le rendu graphique sur les appareils dotés d'écrans compatibles Grâce à ce soutien, votre application peut afficher des bitmaps avec des profils de couleur larges intégrés, chargés à partir de fichiers PNG, JPEG et WebP. via Java ou du code natif. Les applications qui utilisent OpenGL ou Vulkan peuvent générer directement du contenu à large gamme de couleurs (avec Display P3 et scRGB). Cette fonctionnalité est utile pour créer des applications impliquant une reproduction des couleurs haute fidélité, telles que les applications de retouche d'images et de vidéos.
Comprendre le mode large gamme de couleurs
Les profils de couleurs étendus sont des profils ICC, tels que Adobe RVB, Pro Photo RVB et DCI-P3, qui peuvent représenter une gamme de couleurs plus large que sRVB. Les écrans compatibles avec les profils de couleurs étendus peuvent afficher des images avec des couleurs primaires plus profondes (rouges, verts et bleus) ainsi que des couleurs secondaires plus riches (comme les magentas, les cyans et les jaunes).
Sur les appareils Android équipés d'Android 8.0 (niveau d'API 26) ou version ultérieure compatibles, votre application peut activer le mode couleur large gamme de couleurs pour une activité, ce qui permet au système de reconnaître et de traiter correctement les images bitmap avec des profils de couleurs larges intégrés. La
La classe ColorSpace.Named
énumère une liste partielle des types de fichiers couramment utilisés
des espaces colorimétriques
compatibles avec Android.
Remarque:Lorsque le mode large gamme de couleurs est activé, l'état utilise davantage de mémoire et de processeurs GPU pour la composition de l'écran. Avant d'activer le mode plage de couleurs étendue, vous devez bien réfléchir à l'utilité de cette fonctionnalité pour l'activité. Par exemple, une activité qui affiche des photos en plein écran est un bon candidat pour le mode large gamme de couleurs, mais ce n'est pas le cas d'une activité qui affiche de petites miniatures.
Activer le mode large gamme de couleurs
Utilisez l'attribut colorMode
pour demander l'affichage de l'activité.
en mode large gamme de couleurs sur les appareils compatibles. En mode large gamme de couleurs, une fenêtre
en dehors de la gamme sRVB pour afficher des couleurs plus vives. Si l'appareil n'est pas compatible avec l'affichage en mode large gamme de couleurs, cet attribut n'a aucun effet. Si votre application doit déterminer si un écran donné est compatible avec la large gamme de couleurs, appelez la méthode isWideColorGamut()
. Votre application peut aussi appeler
isScreenWideColorGamut()
, qui renvoie true
Uniquement si l'écran offre une large gamme de couleurs et si l'appareil est compatible avec cette fonctionnalité
le rendu des couleurs.
Un écran peut utiliser une large gamme de couleurs, mais ne pas gérer les couleurs. Dans ce cas, n'accordera pas à une application le mode large gamme de couleurs. Lorsqu'un écran n'est pas géré par les couleurs (comme c'était le cas pour toutes les versions d'Android antérieures à la version 8.0), le système remappe les couleurs dessinées par l'application sur la gamme de l'écran.
Pour activer la large gamme de couleurs dans votre activité, définissez l'attribut colorMode
sur wideColorGamut
dans votre fichier AndroidManifest.xml
. Vous devez le faire pour chaque activité pour laquelle vous souhaitez activer le mode large gamme de couleurs.
android:colorMode="wideColorGamut"
Vous pouvez également définir le mode couleur par programmation dans votre activité en appelant la méthode
la méthode setColorMode(int)
et en transmettant
COLOR_MODE_WIDE_COLOR_GAMUT
Afficher du contenu à large gamme de couleurs
Pour afficher du contenu à large gamme de couleurs, votre application doit charger un bitmap à larges couleurs, c'est-à-dire un bitmap avec un profil de couleur contenant un espace colorimétrique plus large que sRVB. Les profils de couleurs larges courants incluent Adobe RVB, DCI-P3 et Display P3.
Votre application peut interroger l'espace de couleurs d'un bitmap en appelant getColorSpace()
. Pour déterminer si le système reconnaît
un espace colorimétrique spécifique à une large gamme, vous pouvez appeler
isWideGamut()
.
La classe Color
vous permet de représenter une couleur avec quatre composants empaquetés dans une valeur de 64 bits, au lieu de la représentation la plus courante qui utilise une valeur entière. En utilisant des valeurs longues, vous
pouvez définir des couleurs avec
plus de précision que les valeurs entières. Si vous devez créer ou encoder une couleur en tant que valeur longue, utilisez
l'une des méthodes pack()
de la classe Color
.
Vous pouvez vérifier si votre application a bien demandé le mode large gamme de couleurs en vérifiant que
la méthode getColorMode()
renvoie
COLOR_MODE_WIDE_COLOR_GAMUT
(cette méthode n'indique pas,
mais si le mode large gamme de couleurs a été accordé).
Utiliser la compatibilité avec la large gamme de couleurs en code natif
Cette section explique comment activer le mode large gamme de couleurs avec la OpenGL et API Vulkan si votre application utilise du code natif.
OpenGL
Pour utiliser le mode plage de couleurs étendue dans OpenGL, votre application doit inclure la bibliothèque EGL 1.4 avec l'une des extensions suivantes :
Pour activer cette fonctionnalité, vous devez d'abord créer un contexte GL via eglChooseConfig
, avec l'un des trois formats de tampon de couleur compatibles pour la couleur étendue dans les attributs. Le format de tampon de couleur pour la couleur étendue doit être l'un des ensembles de valeurs RVBA suivants :
- 8, 8, 8, 8
- 10, 10, 10, 2
- FP16, FP16, FP16, FP16
Ensuite, demandez l'extension d'espace colorimétrique P3 lors de la création de votre cibles de rendu, comme indiqué dans l'extrait de code suivant:
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 prise en charge de la large gamme de couleurs par Vulkan est assurée par l'extension VK_EXT_swapchain_colorspace
.
Avant d'activer la prise en charge étendue des couleurs dans votre code Vulkan, vérifiez d'abord que
est compatible avec
vkEnumerateInstanceExtensionProperties
Si l'extension est disponible, vous devez l'activer pendant
vkCreateInstance
avant de créer les images de la chaîne d'échange qui
utiliser les espaces de couleur supplémentaires définis par l'extension.
Avant de créer la chaîne de permutation, vous devez choisir l'espace colorimétrique souhaité, puis lire en boucle les sur les surfaces physiques disponibles et choisissez un format de couleur valide espace colorimétrique.
Sur les appareils Android, Vulkan est compatible avec la large gamme de couleurs avec les espaces de couleurs et les formats de couleurs VkSurfaceFormatKHR
suivants :
- Espaces colorimétriques Vulkan à large gamme de couleurs :
VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT
VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT
- Formats de couleurs Vulkan compatibles avec une large gamme de couleurs:
VK_FORMAT_R16G16B16A16_SFLOAT
VK_FORMAT_A2R10G10B10_UNORM_PACK32
VK_FORMAT_R8G8B8A8_UNORM
L'extrait de code suivant montre comment vérifier que l'appareil est compatible avec l'espace colorimétrique 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 }
L'extrait de code suivant montre comment demander une chaîne d'échange Vulkan avec
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; }