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ı içeriği oluşturabilir (Display P3 ve scRGB) belirtin. Bu olanak Resim ve video gibi yüksek kalitede renk üretimi içeren uygulamalar oluşturmak için yararlıdır düzenleme'ye dokunun.

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 destekleyen Android cihazlarda uygulamanız sistemin, tanımadığı ve kullandığı bir etkinlik için geniş renk gamı renk modunu yerleştirilmiş geniş renk profillerine sahip bit eşlem resimlerinin doğru şekilde işlenmesini sağlar. İ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ını etkinleştirmeden önce modundaysa etkinliğin gerçekten bu özellikten fayda sağlayıp sağlamadığını dikkatlice düşünmeniz gerekir. Örneğin, Fotoğrafları tam ekran olarak görüntüleyen etkinlikler geniş renk gamı modu için iyi bir adaydır, ancak küçük resimler gösteren bir etkinlik de pek iyi değil.

Geniş renk gamı modunu etkinleştir

Etkinliğin gösterilmesini istemek için colorMode özelliğini kullanın uyumlu cihazlarda geniş renk gamı modunda. Geniş renk gamı modunda bir pencere oluşturulabilir dışında daha canlı renkler kullanın. 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 uygun olsa da renkle yönetilmiyor olabilir. Bu durumda, sistem bir uygulamaya geniş renk gamı moduna izin 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 colorMode özelliğini ayarlayın özelliğini AndroidManifest.xml dosyanızda wideColorGamut olarak belirleyin. 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ı içeriği oluşturun

Şekil 1. P3 (turuncu) ve sRGB (beyaz) renkli alanların karşılaştırması

Geniş renk gamı içeriği oluşturmak için uygulamanızın geniş bir renk bit eşlemi yüklemesi gerekir. Bu bit eşlem, sRGB'den daha geniş bir renk alanı içeren bir renk profili. Yaygın olarak kullanılan geniş renk profilleri şunları içerir: Adobe RGB, DCI-P3 ve Display P3.

Uygulamanız, şunu kullanarak bir bit eşlemin renk alanını sorgulayabilir: getColorSpace() Sistemin bir reklamı tanıyıp tanımadığını belirlemek için özel renk alanını geniş bir gama dönüştürüyorsanız isWideGamut() yöntemini çağırın.

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 birini kullanın:

Bu özelliği etkinleştirmek için önce eglChooseConfig (üçten biri desteklenir) özelliklerdeki geniş renkler için renk arabellek biçimleri kullanma 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 hedefleri:

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ı için Vulkan desteği VK_EXT_swapchain_colorspace uzantısı var.

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.

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

  • 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'ü destekleyip desteklemediğini nasıl kontrol edebileceğiniz gösterilmektedir renk alanı:

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'i, 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;
}