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 บิตแทนการแสดงทั่วไปที่ใช้จำนวนเต็ม
เมื่อใช้ค่าที่ยาว คุณสามารถกำหนดสีได้ด้วย
แม่นยำกว่าค่าจำนวนเต็ม หากต้องการสร้างหรือเข้ารหัสสีเป็นค่าแบบ Long ให้ใช้เมธอด pack()
อย่างใดอย่างหนึ่งในคลาส Color
คุณสามารถตรวจสอบว่าแอปขอโหมดสีกว้างอย่างถูกต้องหรือไม่โดยดูว่าเมธอด getColorMode()
แสดงผลเป็น COLOR_MODE_WIDE_COLOR_GAMUT
หรือไม่ (อย่างไรก็ตาม เมธอดนี้ไม่ได้ระบุว่าระบบให้โหมดสีกว้างจริงหรือไม่)
ใช้การรองรับขอบเขตสีที่กว้างในโค้ดเนทีฟ
ส่วนนี้จะอธิบายวิธีเปิดใช้โหมดสีกว้างด้วย API ของ OpenGL และ Vulkan หากแอปของคุณใช้โค้ดเนทีฟ
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 ที่ใช้พื้นที่สีเพิ่มเติมที่ส่วนขยายกำหนด
ก่อนที่จะสร้าง 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; }