广色域图片Android,广色域照片闪亮登场 Android: 开发者需知两三事

本文探讨了Android应用如何处理DisplayP3和sRGB色彩空间的图片,强调了色彩校正和广色域支持的重要性。通过色彩校正测试和广色域测试,开发者可以确保应用正确显示广色域图像。文章提供了使用BitmapFactory和ImageDecoder进行色彩管理的代码示例,并建议避免假设图片默认为sRGB,而是应检查并转换色彩空间以防止色彩失真。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

874292731f563486308eb159f9e3caed.png

c0b974cc22932deba978856a176ab8a6.png

△ 上图:Display P3,下图: sRGB

b5bd12825c724d43f4050441450bc560.png

874dd79571c0365793314563366a94b6.png

△ 左图:Display P3,右图: sRGB

以上两组图片为同一张照片的 Display P3 和 sRGB 版本。如果您正在使用已校准且支持广色域的显示屏上阅读本文,您会发现两者存在明显差别。

色彩测试

您可通过以下两项测试来判定应用是否已做好支持准备。第一项是色彩校正测试,另一项则是广色域测试。

色彩校正测试: 您的应用能够兼容广色域吗?

如果应用能够主动进行颜色管理,那就说明它已经准备好支持广色域了。在收到图片之后,应用首先会检查图片的色彩空间,然后再根据自身的广色域显色能力,进行必要转换。在这种情况下,即使应用无法处理广色域,图片中的 sRGB 色域仍旧能够正常显示,不存在色彩失真的问题。

下图为内嵌 Display P3 ICC 配置文件的图片进行色彩校正之后的效果。

b7ea354c3192a197fce6a1c652a5b168.png

但是,如果应用不具备色彩校正条件,那么它往往会在色彩空间转换不当的情况下对显示图片进行处理,最终导致图片颜色失真。比如说,您可能会得到下面这种显得褪色且失真的图片。

c796f5e9fe03b894726739c8c329d8b2.png

广色域测试: 您的应用能够支持广色域吗?

如果应用可以显示 sRGB 色彩空间之外的颜色,那就证明它具备支持广色域的能力。您可以利用下面这张图片来测试应用能否支持广色域图像: 若能看到 Android 机器人图标,则说明您的应用可以支持。请注意,该测试需要在具备广色域硬件支持的设备上进行,如 Pixel 3 或三星 Galaxy S10。

9e942a1f8565b10e712b6b9d69ce24f8.png

您需要做哪些准备?

如需正确处理广色域图像,您的应用至少需要通过广色域兼容测试,即色彩校正测试。如果您的应用已测试成功,那就太棒了!尚未通过测试的开发者们也不用着急,您可以按照以下步骤为应用添加支持:

如何才能确保应用做好准备并且满足未来需求呢?关键点在于,应用不可以假设输入的外部图片使用 sRGB 色彩空间,也就是说,应用必须自行检查已解码图片的色彩空间,并进行必要转换。如果没有做到这一点,可能会导致色彩失真,或者色彩配置文件在某个环节不被接受。

必要: 色彩校正

通过色彩校正测试为最低要求。如果应用无法采用广色域,您很有可能只需要把每张图片解码为 sRGB 色彩空间。您可借助 BitmapFactory 或者 ImageDecoder 来实现这个逻辑。

使用 BitmapFactory

在 API 26 中,我们为BitmapFactory.Option添加了inPreferredColorSpace,允许您为已解码的 Bitmap 文件指定目标色彩空间。假设您现在想要解码一个文件,那么您可以用下面的代码进行色彩管理:

BitmapFactory.Option https://developer.android.google.cn/reference/kotlin/android/graphics/BitmapFactory.Options.html

inPreferredColorSpace https://developer.android.google.cn/reference/kotlin/android/graphics/BitmapFactory.Options.html#inPreferredColorSpace:android.graphics.ColorSpace

使用 ImageDecoder

从 Android P (API 等级 28) 开始,我们引入了现代化图片解码工具 ImageDecoder。如果您已将 APK 升级至 API 等级 28 或更高,我们建议您使用 ImageDecoder,而非 BitmapFactory 或 BitmapFactory.Option API。

在以下示例代码中,我们使用 ImageDecoder#decodeBitmap API 将图片转换为 sRGB 位图。

ImageDecoder 的另一个优势在于: 通过传入一个ImageDecoder.OnHeaderDecodedListener并检查ImageDecoder.ImageInfo#getColorSpace,您可以在获取最终的位图之前,就能知道图像的编码色彩空间。这样一来,您便能根据应用对色彩空间的处理方式,来检查图像的编码色彩空间,并分别设置相应的目标色彩空间。

更多使用技巧,请参阅ImageDecoder API 官方文档。

ImageDecoder.OnHeaderDecodedListener https://developer.android.google.cn/reference/android/graphics/ImageDecoder.OnHeaderDecodedListener.html

ImageDecoder.ImageInfo#getColorSpace https://developer.android.google.cn/reference/android/graphics/ImageDecoder.ImageInfo.html#getColorSpace

ImageDecoder API 官方文档 https://developer.android.google.cn/reference/android/graphics/ImageDecoder

已知不良做法

典型的不良做法包括但不限于:

总是假定图片处于 sRGB 色彩空间

没有进行必要转换,便将图片上传为纹理

在压缩时忽略 ICC 配置文件

以上做法均会严重影响用户的视觉体验,令色彩失真。例如,以下示例代码会导致应用色彩校正错误:

在将位图作为纹理上传之前,应用并没有检查色彩空间,因此色彩校正测试的结果会是下面这张失真图片。

9ba9e25bc7698a750543109ec05d5316.png

可选: 支持广色域

为了妥善处理图片,除上述必要变更之外,如果您的应用是一个图像类应用,您可能希望通过采取一些额外措施,例如在清单文件中启用广域模式或创建一个 Display P3 surface,来实现图片的全彩色域显示。

如需在 activity 中启用广色域,请将 AndroidManifest.xml 文件中的colorMode属性设定为wideColorGamut。请注意,您需要为每一个启用广色域模式的 activity 重复以上设置。

您也可以通过程序的方式在 activity 中设定色彩模式,具体方法为: 调用setColorMode(int)方法并传入COLOR_MODE_WIDE_COLOR_GAMUT。

在渲染广色域图像时,除了具体的广色域内容之外,您还需要创建一个广色域 surface,以 OpenGL 为例,应用必须先检查以下扩展:

EXT_gl_colorspace_display_p3_passthrough

EXT_gl_colorspace_display_p3

然后,在创建 surface 时请求 Display P3 作为色彩空间,具体代码见下:

publicEGLSurface createWindowSurface(EGL10 egl, EGLDisplay display,EGLConfig config, Object nativeWindow){EGLSurface surface = null;try{intattribs[] = {EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT,egl.EGL_NONE};surface = egl.eglCreateWindowSurface(display, config, nativeWindow, attribs);} catch(IllegalArgumentException e) {}returnsurface;}

如果您想了解如何在原生代码中采用广色域,请参阅官方文档《使用广色域内容增强图形》。

colorMode https://developer.android.google.cn/reference/android/R.attr.html#colorMode

setColorMode(int) https://developer.android.google.cn/reference/android/view/Window.html#setColorMode(int)

COLOR_MODE_WIDE_COLOR_GAMUT https://developer.android.google.cn/reference/android/content/pm/ActivityInfo.html#COLOR_MODE_WIDE_COLOR_GAMUT

EXT_gl_colorspace_display_p3_passthrough https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_gl_colorspace_display_p3_passthrough.txt

EXT_gl_colorspace_display_p3 https://www.khronos.org/registry/EGL/extensions/EXT/EGL_EXT_gl_colorspace_display_p3.txt

《使用广色域内容增强图形》 https://developer.android.google.cn/training/wide-color-gamut

图片库 API 设计指南

最后,如果您拥有或维护一个图片编解码库,通过色彩校正测试依旧是最低要求。为了现代化您的图片库,我们强烈建议您进行下列两项工作以扩展色彩管理 API:

在设计新 API 或扩展现有 API 时,请显式传入 ColorSpace 参数。相比于硬编码一个色彩空间,显式的 ColorSpace 参数更能满足未来开发工作的需求。

所有旧版本 API 应该显式将位图解码为 sRGB 色彩空间。在 Android 8.0 (API 等级 26) 引入色彩管理之前,所有内容都被设定为 sRGB 色域。此项操作有助于您确保客户应用向后兼容。

ColorSpace https://developer.android.google.cn/reference/android/graphics/ColorSpace

完成上述工作后,就请着手开展前文所述的两项色彩测试工作吧!

点击屏末|阅读原文| 了解更多移动开发相关产品内容

1adf6d16787a709c69ac054e5887fd9c.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值