Android 8.0 (API ระดับ 26) เปิดตัวการรองรับการจัดการสีสำหรับ พื้นที่สีนอกเหนือจาก RGB (sRGB) มาตรฐานสำหรับแสดงผลกราฟิกในอุปกรณ์ที่มีจอแสดงผลที่เข้ากันได้ การสนับสนุนนี้จะทำให้ แอปของคุณสามารถแสดงผลบิตแมปด้วยโปรไฟล์สีแบบกว้างที่ฝังอยู่ซึ่งโหลดจากไฟล์ PNG, JPEG และ WebP ผ่าน Java หรือโค้ดแบบเนทีฟ แอปที่ใช้ OpenGL หรือ Vulkan จะสามารถแสดงผลเนื้อหาขอบเขตสีแบบกว้างได้โดยตรง (ใช้ Display P3 และ scRGB) ความสามารถนี้ มีประโยชน์สำหรับการสร้างแอปที่อาศัยการสร้างสีที่มีความแม่นยำสูง เช่น รูปภาพและวิดีโอ แอปตัดต่อ
ทำความเข้าใจโหมด Wide Color gamut
โปรไฟล์สีกว้างคือ โปรไฟล์ ICC เช่น Adobe RGB Pro Photo RGB และ DCI-P3 ซึ่งก็คือ สามารถแสดงช่วงสีได้กว้างกว่า sRGB หน้าจอที่รองรับโปรไฟล์สีกว้าง สามารถแสดงรูปภาพที่มีสีหลักเข้มกว่า (สีแดง เขียว และน้ำเงิน) และสีรองที่เข้มขึ้น สีต่างๆ (เช่น ม่วงแดง ฟ้าเขียว และเหลือง)
ในอุปกรณ์ Android ที่ใช้ Android 8.0 (API ระดับ 26) ขึ้นไปและรองรับ แอปสามารถ
เปิดใช้โหมดสีขอบเขตสีแบบกว้างสำหรับกิจกรรมที่ระบบรู้จักและ
ประมวลผลภาพบิตแมปที่มีโปรไฟล์สีกว้างฝังอยู่อย่างถูกต้อง
คลาส ColorSpace.Named
แจกแจงรายการบางส่วนของที่ใช้กันโดยทั่วไป
พื้นที่สีที่ Android รองรับ
หมายเหตุ: เมื่อเปิดใช้โหมดขอบเขตสีแบบกว้าง กิจกรรม ใช้หน่วยความจำและการประมวลผล GPU มากขึ้นในการจัดองค์ประกอบหน้าจอ ก่อนเปิดใช้ขอบเขตสีแบบกว้าง คุณควรพิจารณาอย่างรอบคอบว่ากิจกรรมนั้นจะได้รับประโยชน์จริงๆ หรือไม่ ตัวอย่างเช่น กิจกรรมที่แสดงรูปภาพแบบเต็มหน้าจอเป็นตัวเลือกที่ดีสำหรับโหมดขอบเขตสีที่กว้าง แต่ กิจกรรมที่แสดงภาพขนาดย่อขนาดเล็กนั้นไม่ได้เป็นเช่นนั้น
เปิดใช้โหมดขอบเขตสีแบบกว้าง
ใช้แอตทริบิวต์ colorMode
เพื่อขอให้แสดงกิจกรรม
ในโหมดช่วงสีกว้างในอุปกรณ์ที่เข้ากันได้ ในโหมดขอบเขตสีกว้าง หน้าต่างสามารถแสดงผลได้
อยู่นอกขอบเขต sRGB เพื่อแสดงสีที่สดใสมากขึ้น หากอุปกรณ์ไม่รองรับ Wide Color
การแสดงผลแบบ Gamut แอตทริบิวต์นี้จะไม่มีผล หากแอปของคุณต้องกำหนดว่า
การแสดงผลนั้นใช้ขอบเขตสีได้กว้าง
isWideColorGamut()
วิธี คุณยังเรียกใช้แอป
isScreenWideColorGamut()
ซึ่งแสดงผล true
เฉพาะเมื่อจอแสดงผลรองรับขอบเขตสีแบบกว้างและอุปกรณ์รองรับขอบเขตสีแบบกว้างเท่านั้น
การแสดงสี
จอแสดงผลอาจมีขอบเขตสีที่กว้าง แต่ไม่มีการจัดการสี ซึ่งในกรณีนี้ ระบบจะไม่ให้สิทธิ์โหมดขอบเขตสีแบบกว้างแก่แอป เมื่อจอแสดงผลไม่มีการจัดการสี เช่นเดียวกับกรณีของ Android ทุกเวอร์ชันก่อน 8.0 ระบบจะแมป ที่แอปวาดในช่วงขอบเขตของจอแสดงผล
หากต้องการเปิดใช้ขอบเขตสีแบบกว้างในกิจกรรม ให้ตั้งค่า colorMode
เป็น wideColorGamut
ในไฟล์ AndroidManifest.xml
ของคุณ คุณ
สำหรับแต่ละกิจกรรมที่ต้องการเปิดใช้โหมด Wide Color
android:colorMode="wideColorGamut"
คุณยังสามารถตั้งค่าโหมดสีแบบเป็นโปรแกรมในกิจกรรมได้ด้วยการเรียกใช้
setColorMode(int)
เมธอดและการส่งใน
COLOR_MODE_WIDE_COLOR_GAMUT
แสดงผลเนื้อหา Wide Color gamut
ในการแสดงผลเนื้อหา Wide Color gamut แอปของคุณต้องโหลดบิตแมป สีแบบกว้าง ซึ่งเป็นบิตแมปที่มี โปรไฟล์สีที่มีพื้นที่สีที่กว้างกว่า sRGB โปรไฟล์สีแบบกว้างที่พบบ่อย ได้แก่ Adobe RGB, DCI-P3 และ Display P3
แอปของคุณสามารถค้นหาพื้นที่สีของบิตแมปได้ด้วยการเรียก
getColorSpace()
เพื่อดูว่าระบบรู้จัก
พื้นที่สีที่เจาะจงให้ขอบเขตกว้าง คุณสามารถเรียกใช้
isWideGamut()
วิธี
คลาส Color
ให้คุณแสดงสีด้วยองค์ประกอบ 4 รายการ
เป็นค่ายาว 64 บิตแทนการแสดงทั่วไปที่ใช้จำนวนเต็ม
เมื่อใช้ค่าที่ยาว คุณสามารถกำหนดสีได้ด้วย
แม่นยำกว่าค่าจำนวนเต็ม หากต้องการสร้างหรือเข้ารหัสสีเป็นค่าแบบยาว ให้ใช้
หนึ่งในเมธอด pack()
ในชั้นเรียน Color
คุณสามารถตรวจสอบว่าแอปขอโหมดขอบเขตสีกว้างอย่างถูกต้องหรือไม่ โดยตรวจสอบว่า
เมธอด getColorMode()
แสดงผล
COLOR_MODE_WIDE_COLOR_GAMUT
(วิธีนี้ไม่ได้ระบุ
อย่างไรก็ตาม ได้ให้สิทธิ์โหมดขอบเขตสีแบบกว้างหรือไม่)
ใช้การรองรับขอบเขตสีแบบกว้างในโค้ดแบบเนทีฟ
ส่วนนี้จะอธิบายวิธีเปิดใช้โหมดขอบเขตสีแบบกว้างด้วยองค์ประกอบ OpenGL และ Vulkan API หากแอปใช้โค้ดแบบเนทีฟ
OpenGL
ในการใช้โหมดขอบเขตสีแบบกว้างใน OpenGL แอปของคุณต้องมีไลบรารี EGL 1.4 ด้วย หนึ่งในส่วนขยายต่อไปนี้
หากต้องการเปิดใช้ฟีเจอร์ คุณต้องสร้างบริบท GL ก่อนโดยใช้
eglChooseConfig
ที่รองรับ 1 ใน 3 นี้
รูปแบบบัฟเฟอร์สีสำหรับสีกว้างในแอตทริบิวต์ รูปแบบบัฟเฟอร์สีสำหรับ แบบกว้าง
สีต้องเป็นหนึ่งในชุดค่า RGBA เหล่านี้
- 8, 8, 8, 8
- 10, 10, 10, 2
- FP16, FP16, FP16, FP16
จากนั้น ให้ขอส่วนขยายพื้นที่สี P3 เมื่อสร้าง แสดงผลเป้าหมาย ดังที่แสดงในข้อมูลโค้ดต่อไปนี้
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 รองรับขอบเขตสีแบบกว้างผ่าน
ส่วนขยาย VK_EXT_swapchain_colorspace
ก่อนที่จะเปิดใช้งานการสนับสนุน Wide Color ในโค้ด Vulkan ก่อนอื่นให้ตรวจสอบว่า
ส่วนขยายได้รับการสนับสนุนผ่าน
vkEnumerateInstanceExtensionProperties
หากส่วนขยายพร้อมใช้งาน คุณต้องเปิดใช้ระหว่าง
vkCreateInstance
ก่อนสร้างรูปภาพการสลับเชนใดๆ ที่
ใช้พื้นที่สีเพิ่มเติมที่กำหนดโดยส่วนขยาย
ก่อนที่จะสร้าง Swapchain คุณต้องเลือกพื้นที่สีที่ต้องการ จากนั้นวนซ้ำ พื้นผิวจริงของอุปกรณ์ที่พร้อมจำหน่ายและเลือกรูปแบบสีที่ถูกต้องสำหรับรูปแบบสีดังกล่าว พื้นที่สี
ในอุปกรณ์ Android Vulkan รองรับขอบเขตสีแบบกว้างสำหรับพื้นที่สีต่อไปนี้และ
รูปแบบสี VkSurfaceFormatKHR
:
- ช่องว่างสีแบบกว้าง Vulkan
VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT
VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT
- รูปแบบสี Vulkan ที่มีการรองรับขอบเขตสีแบบกว้าง
VK_FORMAT_R16G16B16A16_SFLOAT
VK_FORMAT_A2R10G10B10_UNORM_PACK32
VK_FORMAT_R8G8B8A8_UNORM
ข้อมูลโค้ดต่อไปนี้แสดงวิธีตรวจสอบว่าอุปกรณ์รองรับ 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 }
ข้อมูลโค้ดต่อไปนี้แสดงวิธีขอสลับ Vulkan ด้วย
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; }