Grafiken mit Wide-Color-Inhalten optimieren

Unter Android 8.0 (API-Level 26) wurde die Unterstützung für die Farbverwaltung Farbräume außer Standard-RGB (sRGB) zur Darstellung von Grafiken auf Geräten mit kompatiblen Bildschirmen Dank dieser Unterstützung Ihre App kann Bitmaps mit eingebetteten breiten Farbprofilen rendern, die aus PNG-, JPEG- und WebP-Dateien geladen wurden über Java oder nativen Code. Apps, die OpenGL oder Vulkan verwenden, können Inhalte mit erweitertem Farbraum direkt ausgeben (Display P3 und scRGB). Diese Funktion ist nützlich für die Erstellung von Apps mit einer High-Fidelity-Farbwiedergabe, z. B. für Bilder und Videos zum Bearbeiten von Apps.

Informationen zum großen Farbgamut-Modus

Profile mit erweitertem Farbraum sind ICC-Profile wie Adobe RGB, ProPhoto RGB und DCI-P3, die einen größeren Farbbereich als sRGB darstellen können. Bildschirme, die breite Farbprofile unterstützen können Bilder mit tieferen Primärfarben (Rot-, Grün- und Blautöne) sowie satteren sekundären Farben anzeigen. (z. B. Magenta, Cyan und Gelb).

Auf Android-Geräten mit Android 8.0 (API-Level 26) oder höher, die diese Funktion unterstützen, kann Ihre App den Farbmodus mit erweitertem Farbraum für eine Aktivität aktivieren. Dadurch erkennt und verarbeitet das System Bitmap-Bilder mit eingebetteten Wide-Gamut-Profilen korrekt. Die Die ColorSpace.Named-Klasse führt eine unvollständige Liste häufig verwendeter die von Android unterstützt werden.

Hinweis:Wenn der Modus für den großen Farbgamut aktiviert ist, sehen Sie "window" benötigt mehr Arbeitsspeicher und GPU-Verarbeitung für die Bildschirmzusammensetzung. Bevor Sie den Modus mit erweitertem Farbraum aktivieren, sollten Sie sorgfältig überlegen, ob die Aktivität davon wirklich profitiert. Beispiel: zur Anzeige von Fotos im Vollbildmodus eignet sich gut für den Breitfarbmodus. bei einer Aktivität mit kleinen Miniaturansichten hingegen nicht.

Modus mit erweitertem Farbraum aktivieren

Verwenden Sie das Attribut colorMode, um das Anzeigen der Aktivität anzufordern auf kompatiblen Geräten im Breitfarbmodus. Im Modus mit erweitertem Farbraum kann ein Fenster außerhalb des sRGB-Farbraums gerendert werden, um kräftigere Farben zu erzielen. Wenn das Gerät kein Wide-Gamut-Rendering unterstützt, hat dieses Attribut keine Auswirkungen. Wenn Ihre App feststellen muss, ob ein bestimmtes Display einen erweiterten Farbraum unterstützt, rufen Sie die Methode isWideColorGamut() auf. Ihre App kann auch isScreenWideColorGamut() aufrufen. Diese Funktion gibt true nur zurück, wenn das Display einen erweiterten Farbraum unterstützt und das Gerät die Farbwiedergabe mit erweitertem Farbraum unterstützt.

Ein Display kann für eine große Farbpalette geeignet, aber nicht für die Farbverwaltung geeignet sein. In diesem Fall System gewährt einer App den Modus für den breiten Farbgamut-Modus nicht. Wenn ein Display nicht farbverwaltet wird – wie bei allen Android-Versionen vor 8.0 –, werden die von der App gezeichneten Farben vom System in den Farbraum des Displays umgewandelt.

Um die große Farbskala in deiner Aktivität zu aktivieren, lege die colorMode fest. in Ihrer AndroidManifest.xml-Datei auf wideColorGamut setzen. Ich müssen Sie dies für jede Aktivität tun, für die Sie den breiten Farbmodus aktivieren möchten.

android:colorMode="wideColorGamut"

Sie können den Farbmodus auch programmatisch in Ihrer Aktivität festlegen, indem Sie die Methode setColorMode(int) aufrufen und COLOR_MODE_WIDE_COLOR_GAMUT übergeben.

Inhalt mit breitem Farbgamut rendern

Abbildung 1. Display P3-Farbraum (orange) im Vergleich zum sRGB-Farbraum (weiß)

Wenn Sie Inhalte mit erweitertem Farbraum rendern möchten, muss Ihre App eine Wide-Color-Bitmap laden, also eine Bitmap mit einem Farbprofil, das einen größeren Farbraum als sRGB enthält. Gängige Profile für breite Farbräume sind Adobe RGB, DCI-P3 und Display P3.

Ihre App kann den Farbraum einer Bitmap abfragen, indem getColorSpace() aufgerufen wird. Um zu ermitteln, ob das System ein Farbraum als breite Palette auswählen, können Sie die Methode isWideGamut()-Methode.

Mit der Klasse Color können Sie eine Farbe mit vier Komponenten in einem 64-Bit-Wert darstellen, anstatt der gängigen Darstellung mit einem Ganzzahlwert. Mithilfe von Long-Werten können Sie Farben genauer definieren als mit Ganzzahlwerten. Wenn Sie eine Farbe als Long-Wert erstellen oder codieren möchten, verwenden Sie eine der pack()-Methoden in der Color-Klasse.

Sie können überprüfen, ob Ihre App den Modus für den breiten Farbgamut-Modus ordnungsgemäß angefordert hat, indem Sie gibt die Methode getColorMode() COLOR_MODE_WIDE_COLOR_GAMUT (diese Methode gibt nicht an, ob der breite Farbgamut-Modus tatsächlich zugelassen wurde.

Unterstützung für breite Farbskala im nativen Code verwenden

In diesem Abschnitt wird beschrieben, wie Sie den Modus mit erweitertem Farbraum mit den APIs OpenGL und Vulkan aktivieren, wenn Ihre App nativen Code verwendet.

OpenGL

Um den Weitwinkel-Gamut-Modus in OpenGL zu verwenden, muss Ihre App die EGL 1.4-Bibliothek mit eine der folgenden Erweiterungen:

Zum Aktivieren der Funktion müssen Sie zuerst einen GL-Kontext erstellen über eglChooseConfig, mit einer der drei unterstützten Farbpufferformate für breite Farben in den Attributen. Das Farbpufferformat für Breit Farbe muss einer der folgenden RGBA-Werte sein:

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

Fordere dann beim Erstellen deiner Renderziele die P3-Farbraumerweiterung an, wie im folgenden Code-Snippet gezeigt:

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

Die Vulkan-Unterstützung für einen erweiterten Farbraum wird über die Erweiterung VK_EXT_swapchain_colorspace bereitgestellt.

Bevor Sie im Vulkan-Code die Unterstützung von breiten Farben aktivieren, prüfen Sie zuerst, ob die Erweiterung wird unterstützt über vkEnumerateInstanceExtensionProperties Wenn die Erweiterung verfügbar ist, müssen Sie sie während vkCreateInstance aktivieren, bevor Sie Swapchain-Images erstellen, die die von der Erweiterung definierten zusätzlichen Farbräume verwenden.

Bevor Sie die Swapchain erstellen, müssen Sie den gewünschten Farbraum auswählen und dann durch die verfügbaren Oberflächen für das Gerät und wählen Sie ein gültiges Farbformat dafür aus. Farbraum.

Auf Android-Geräten unterstützt Vulkan den erweiterten Farbraum mit den folgenden Farbräumen und VkSurfaceFormatKHR-Farbformaten:

  • Vulkan-Farbräume mit erweitertem Farbraum:
    • VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT
    • VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT
  • Vulkan-Farbformate mit Unterstützung für einen erweiterten Farbraum:
    • VK_FORMAT_R16G16B16A16_SFLOAT
    • VK_FORMAT_A2R10G10B10_UNORM_PACK32
    • VK_FORMAT_R8G8B8A8_UNORM

Im folgenden Code-Snippet wird gezeigt, wie Sie prüfen können, ob das Gerät den Display P3-Farbraum unterstützt:

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
}

Das folgende Code-Snippet zeigt, wie Sie mit VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT einen Vulkan-Swapchain anfordern:

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;
}