Geniş renkli içerikle grafikleri geliştirin

Android 8.0 (API düzeyi 26), ek özellikler için renk yönetimi renk alanları uyumlu ekranlara sahip cihazlarda grafik oluşturmak için standart RGB (sRGB) Bu destek sayesinde Uygulamanız PNG, JPEG ve WebP dosyalarından yüklenen yerleşik geniş renk profillerine sahip bit eşlemler oluşturabilir yerel kod aracılığıyla da ekleyebilirsiniz. OpenGL veya Vulkan kullanan uygulamalar, doğrudan geniş renk gamına sahip içerikler yayınlayabilir (Display P3 ve scRGB kullanılarak). Bu özellik, resim ve video düzenleme uygulamaları gibi yüksek kaliteli renk üretimi içeren uygulamalar oluşturmak için kullanışlıdır.

Geniş renk gamı modunu anlama

Geniş renk profilleri ICC profilleri; örneğin, Adobe RGB Pro Photo RGB ve DCI-P3 sRGB'den daha geniş bir renk aralığını temsil edebilir. Geniş renk profillerini destekleyen ekranlar birincil renkleri daha koyu (kırmızı, yeşil ve mavi) ve ikincil renkler daha zengin renkleri (örneğin, macenta, camgöbeği ve sarılar).

Android 8.0 (API düzeyi 26) veya sonraki sürümleri çalıştıran ve bu özelliği destekleyen Android cihazlarda uygulamanız, sistemin yerleşik geniş renk profillerine sahip bitmap resimlerini tanıyıp doğru şekilde işlediği bir etkinlik için geniş renk gamına sahip renk modunu etkinleştirebilir. İlgili içeriği oluşturmak için kullanılan ColorSpace.Named sınıfı, yaygın olarak kullanılan ürünlerin bir kısmi listesini numaralandırır renk boşluklarından oluşuyor.

Not: Geniş renk gamı modu etkinleştirildiğinde, etkinlik penceresi, ekran kompozisyonu için daha fazla bellek ve GPU işlemesi kullanır. Geniş renk gam modunu etkinleştirmeden önce, etkinliğin bundan gerçekten faydalanıp faydalanmadığını dikkatlice değerlendirmeniz gerekir. Örneğin, fotoğrafları tam ekranda gösteren bir etkinlik geniş renk gam modu için iyi bir adaydır ancak küçük küçük resimler gösteren bir etkinlik için iyi bir aday değildir.

Geniş renk gam modunu etkinleştirme

Etkinliğin uyumlu cihazlarda geniş renk gamında gösterilmesini istemek için colorMode özelliğini kullanın. Geniş renk gamı modunda bir pencere, daha canlı renkler görüntülemek için sRGB gamının dışında oluşturma yapabilir. Cihaz geniş renk özelliğini desteklemiyorsa bu özelliğin herhangi bir etkisi yoktur. Uygulamanızın, belirli bir verinin geniş renk gamı varsa isWideColorGamut() yöntemini çağırın. Uygulamanız ayrıca isScreenWideColorGamut(), true değerini döndürür. yalnızca ekran geniş renk gamı kullanılabiliyorsa ve cihaz geniş renk gamını destekliyorsa renk oluşturma.

Bir ekran geniş renk gamına sahip olabilir ancak renk yönetimi özelliğine sahip olmayabilir. Bu durumda sistem, uygulamaya geniş renk gamını vermez. Ekran renk yönetimli değilse (8.0'dan önceki tüm Android sürümlerinde olduğu gibi) sistem, uygulama tarafından çizilen renklerin ekran gamına uymasını sağlar.

Etkinliğinizde geniş renk gamını etkinleştirmek için AndroidManifest.xml dosyanızdaki colorMode özelliğini wideColorGamut olarak ayarlayın. Siz bunu, geniş renk modunu etkinleştirmek istediğiniz her etkinlik için yapmanız gerekir.

android:colorMode="wideColorGamut"

Ayrıca, setColorMode(int) yöntemi ve değerlendirmesi COLOR_MODE_WIDE_COLOR_GAMUT.

Geniş renk gamına sahip içerik oluşturma

Şekil 1. Display P3 (turuncu) ve sRGB (beyaz) renk alanları

Geniş renk gamına sahip içerikleri oluşturmak için uygulamanızın geniş renkli bir bitmap yüklemesi gerekir. Bu bitmap, sRGB'den daha geniş bir renk alanı içeren bir renk profiline sahip olmalıdır. Yaygın geniş renk profilleri arasında Adobe RGB, DCI-P3 ve Display P3 bulunur.

Uygulamanız, getColorSpace() işlevini çağırarak bir bitmap'in renk alanını sorgulayabilir. Sistemin belirli bir renk alanını geniş gamut olarak tanıyıp tanımadığını belirlemek için isWideGamut() yöntemini çağırabilirsiniz.

Color sınıfı, dört bileşenden oluşan bir rengi temsil etmenizi sağlar. tamsayıların kullanıldığı en yaygın gösterim yerine 64 bit uzunluğunda bir değer içine yerleştirilmiştir değer. Uzun değerler kullanarak, renkleri tanımlayabilirsiniz. tam sayı değerlerine göre daha hassastır. Bir rengi uzun değer olarak oluşturmanız veya kodlamanız gerekirse Color sınıfındaki pack() yöntemlerinden biri.

Uygulamanızın geniş renk gamı modunu düzgün bir şekilde isteyip istemediğini doğrulayarak getColorMode() yöntemi şunu döndürür: COLOR_MODE_WIDE_COLOR_GAMUT (bu yöntem, (geniş renk gamı modunun gerçekten verilip verilmediğini) kontrol edin.

Yerel kodda geniş renk gam desteğini kullanma

Bu bölümde, OpenGL ve Uygulamanız yerel kod kullanıyorsa Vulkan API'leri.

OpenGL

OpenGL'de geniş renk gam modunu kullanmak için uygulamanızın aşağıdaki uzantılardan biriyle EGL 1.4 kitaplığını içermesi gerekir:

Özelliği etkinleştirmek için önce eglChooseConfig aracılığıyla bir GL bağlamı oluşturmanız gerekir. Bu bağlamda, özelliklerde geniş renk için desteklenen üç renk arabellek biçiminden birini kullanmanız gerekir. Geniş color [renk] şu RGBA değer gruplarından biri olmalıdır:

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

Ardından, aşağıdaki kod snippet'inde gösterildiği gibi oluşturma hedeflerinizi oluştururken P3 renk alanı uzantısını isteyin:

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 Dili

Geniş renk gamına yönelik Vulkan desteği, VK_EXT_swapchain_colorspace uzantısı aracılığıyla sağlanır.

Vulkan kodunuzda geniş renk desteğini etkinleştirmeden önce uzantısı, vkEnumerateInstanceExtensionProperties Uzantı kullanılabiliyorsa şu tarihte etkinleştirmeniz gerekir: vkCreateInstance gibi görünen takas zinciri resimleri uzantının tanımladığı ek renk alanlarını kullanın.

Takas zincirini oluşturmadan önce istediğiniz renk alanını seçmeniz ve ardından kullanılabilir fiziksel cihaz yüzeylerini seçin ve bunun için geçerli bir renk biçimi seçin kullanabilirsiniz.

Android cihazlarda Vulkan, aşağıdaki renk alanlarıyla ve VkSurfaceFormatKHR renk biçimleriyle geniş renk gamını destekler:

  • Vulkan geniş renk gamı renk alanları:
    • VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT
    • VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT
  • Geniş renk gam desteğine sahip Vulkan renk biçimleri:
    • VK_FORMAT_R16G16B16A16_SFLOAT
    • VK_FORMAT_A2R10G10B10_UNORM_PACK32
    • VK_FORMAT_R8G8B8A8_UNORM

Aşağıdaki kod snippet'inde, cihazın Display P3 renk alanını destekleyip desteklemediğini nasıl kontrol edebileceğiniz gösterilmektedir:

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
}

Aşağıdaki kod snippet'inde, VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT ile Vulkan takas zinciri isteğinin nasıl yapılacağı gösterilmektedir:

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