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 direkt Inhalte mit breitem Farbgamut ausgeben (für 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

Breite Farbprofile sind ICC-Profile wie Adobe RGB <ph type="x-smartling-placeholder"></ph> Pro Photo RGB und DCI-P3, die kann einen größeren Farbbereich als sRGB darstellen. 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 dies unterstützen, kann deine App den Weitfarbfarbmodus für eine Aktivität aktivieren, bei der das System erkennt und Bitmapbilder mit eingebetteten breiten Farbprofilen korrekt verarbeiten 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. Vor dem Aktivieren der großen Farbgamut sollten Sie genau überlegen, ob die Aktivität wirklich davon profitiert. Beispiel: zur Anzeige von Fotos im Vollbildmodus eignet sich gut für den Breitfarbmodus. bei einer Aktivität mit kleinen Miniaturansichten hingegen nicht.

Breiten Farbgamut-Modus aktivieren

Verwenden Sie das Attribut colorMode, um das Anzeigen der Aktivität anzufordern auf kompatiblen Geräten im Breitfarbmodus. Im Breitfarbmodus kann ein Fenster außerhalb der sRGB-Farbskala stehen, um kräftigere Farben darzustellen. Wenn das Gerät keine breiten Farben unterstützt Gamut-Rendering enthält, hat dieses Attribut keine Auswirkung. Wenn Ihre App feststellen muss, das Display mit Breitfarbpalette kompatibel ist, rufen Sie die Methode isWideColorGamut()-Methode. Sie können die App auch anrufen, isScreenWideColorGamut() gibt true zurück Nur wenn der Bildschirm für den großen Farbraum geeignet ist und das Gerät einen breiten Farbraum unterstützt. Farbwiedergabe.

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 farblich verwaltet wird Wie bei allen Versionen von Android vor 8.0 ordnet das System die von der App gezeichnete Farben in der Farbpalette des Bildschirms.

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)-Methode und Übergabe COLOR_MODE_WIDE_COLOR_GAMUT.

Inhalt mit breitem Farbgamut rendern

<ph type="x-smartling-placeholder">
</ph>
Abbildung 1. Display P3 (orange) im Vergleich zu sRGB (weiß)

Um Inhalte mit breiter Farbskala zu rendern, muss Ihre App eine Bitmap in breiten Farben laden, also eine Bitmap mit ein Farbprofil mit einem Farbraum, der breiter als sRGB ist. Gängige breite Farbprofile sind Adobe RGB, DCI-P3 und Display P3

Ihre App kann den Farbraum einer Bitmap abfragen, indem sie getColorSpace() 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 darstellen in einen 64-Bit-Wert verpackt anstelle der gebräuchlichsten Darstellung, die eine Ganzzahl verwendet Wert. Mit langen Werten können Sie Farben mit höhere Genauigkeit als Ganzzahlwerte. Wenn Sie eine Farbe als Long-Wert erstellen oder codieren müssen, verwenden Sie Eine der pack()-Methoden in der Klasse Color.

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 Weitwinkel-Farbgamut-Modus mit der OpenGL und Vulkan APIs, 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

Fordern Sie dann beim Erstellen der Anzeige die Erweiterung für den P3-Farbraum an. Renderingziele wie im folgenden Code-Snippet dargestellt:

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 unterstützt eine breite Farbskala über den Erweiterung VK_EXT_swapchain_colorspace.

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, bevor Sie Swapchain-Bilder erstellen, die Verwenden Sie die durch die Erweiterung definierten zusätzlichen Farbräume.

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 eine große Farbskala mit den folgenden Farbräumen und VkSurfaceFormatKHR Farbformate:

  • Vulkan-Farbräume mit breiter Farbskala: <ph type="x-smartling-placeholder">
      </ph>
    • VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT
    • VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT
  • Vulkan-Farbformate mit Unterstützung für breite Farbskala: <ph type="x-smartling-placeholder">
      </ph>
    • VK_FORMAT_R16G16B16A16_SFLOAT
    • VK_FORMAT_A2R10G10B10_UNORM_PACK32
    • VK_FORMAT_R8G8B8A8_UNORM

Das folgende Code-Snippet zeigt, wie Sie prüfen können, ob das Gerät das Display P3 unterstützt Farbraum:

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:

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