Android应用开发(24)启用广色域(wideColorGamut)

Android应用开发学习笔记——目录索引

 参考android官网:

使用广色域内容增强图形效果  |  Android 开发者  |  Android Developers

ColorSpace  |  Android Developers

Wide Color Photos Are Coming to Android: Things You Need to Know to be Prepared

  • 广色域图片下载

Android 现已迎来新一轮的图像革新, Android 8.0(API 级别 26)或更高的 Android 版本上,应用可为 Activity 启用广色域颜色模式,色域更宽的画面意味着,能给用户呈现更加实景的丰富的色彩。

切入正题之前,让我先解答一下大家的疑惑: 为什么要支持广色域呢?实际上,移动设备的屏幕与摄像头传感器每年都在更新换代,越来越多的新机型即将搭载校准显示面板,其中部分还会提供广色域支持。现代摄像头感应器能够捕捉到 sRGB 范围以外的颜色,然后生成广色域图片。屏幕与传感器的双重升级将带给用户端到端的摄影体验,让他们用更鲜明的色彩留影真实世界。

从技术层面来说,这意味着应用需要处理的图片与之前不同了。图片内嵌的 ICC 配置文件将不再采用 sRGB 色彩空间,而是转用其它色域更加丰富的格式,如 Display P3 和 Adobe RGB。对于消费者而言,广色域能让照片看上去更加真实。

一、check广色域支持情况

如果是debug,可以使用adb shell dumpsys SurfaceFlinger --wide-color

使用xiaomi 13 Ultra(android 13 API 级别 33)运行命令输出如下:

使用MIX 2S(android API 级别 29)运行命令输出如下:

显示屏是否支持广色域,请调用 isWideColorGamut() 方法。

应用还可以调用 isScreenWideColorGamut()

mDisplay = getWindowManager().getDefaultDisplay();
Log.d(TAG, "isWideColorGamut(): " + mDisplay.isWideColorGamut());

boolean isWcgSupport = 
        getResources().getConfiguration().isScreenWideColorGamut();
Log.d(TAG, "isScreenWideColorGamut(): " + isWcgSupport);

 使用xiaomi 13 Ultra(android 13 API 级别 33)log打印:

07-31 00:21:49.959 13998 13998 D lzl-test: isWideColorGamut(): true
07-31 00:21:49.959 13998 13998 D lzl-test: isScreenWideColorGamut(): true

 使用MIX 2S(android API 级别 29)log打印:

07-31 00:17:49.405 13998 13998 D lzl-test: isWideColorGamut(): false
07-31 00:17:49.405 13998 13998 D lzl-test: isScreenWideColorGamut(): false

二、启用广色域模式

为了妥善处理图片,除上述必要check之外,如果是一个图像类应用,可用通过如下方式启用广色域模式,来实现图片的全彩色域显示:

  1.  AndroidManifest.xml 在 activity 文件中的 colorMode 属性设定为 wideColorGamut

  2. 调用API setColorMode(ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT);

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


        <activity
            android:name=".WideColorActivity"
            android:colorMode="wideColorGamut"
            android:exported="true">
            ...
        </activity>

        <activity
            android:name=".WideColorActivity2"
            android:colorMode="wideColorGamut"
            android:exported="false">
            ...
        </activity>

通过代码setColorMode(ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT)设置一个 Display P3 surface,来实现图片的全彩色域显示。 

getWindow().setColorMode(ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT);
Log.d(TAG, "getWindow().getColorMode(): " + getWindow().getColorMode());

代码简单分析:

//frameworks/base/core/java/android/view/Window.java
    /**
     * <p>Sets the requested color mode of the window. The requested the color mode might
     * override the window's pixel {@link WindowManager.LayoutParams#format format}.</p>
     *
     * <p>The requested color mode must be one of {@link ActivityInfo#COLOR_MODE_DEFAULT},
     * {@link ActivityInfo#COLOR_MODE_WIDE_COLOR_GAMUT} or {@link ActivityInfo#COLOR_MODE_HDR}.</p>
     *
     * <p>The requested color mode is not guaranteed to be honored. Please refer to
     * {@link #getColorMode()} for more information.</p>
     *
     * @see #getColorMode()
     * @see Display#isWideColorGamut()
     * @see Configuration#isScreenWideColorGamut()
     */
    public void setColorMode(@ActivityInfo.ColorMode int colorMode) {
        final WindowManager.LayoutParams attrs = getAttributes();
        attrs.setColorMode(colorMode);
        dispatchWindowAttributesChanged(attrs);
    }

    protected void dispatchWindowAttributesChanged(WindowManager.LayoutParams attrs) {
        if (mCallback != null) {
            mCallback.onWindowAttributesChanged(attrs);
        }
    }

// frameworks/base/core/java/android/view/WindowManager.java
        public void setColorMode(@ActivityInfo.ColorMode int colorMode) {
            mColorMode = colorMode;
        }


// Activity.java (android\frameworks\base\core\java\android\app)
    public void onWindowAttributesChanged(WindowManager.LayoutParams params) {
        // Update window manager if: we have a view, that view is
        // attached to its parent (which will be a RootView), and
        // this activity is not embedded.
        if (mParent == null) {
            View decor = mDecor;
            if (decor != null && decor.getParent() != null) {
                getWindowManager().updateViewLayout(decor, params);
                if (mContentCaptureManager != null) {
                    mContentCaptureManager.updateWindowAttributes(params);
                }
            }
        }
    }
    
// WindowManagerImpl.java (android\frameworks\base\core\java\android\view)
    public void updateViewLayout(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
        android.util.SeempLog.record_vg_layout(384,params);
        applyTokens(params);
        mGlobal.updateViewLayout(view, params);
    }
// WindowManagerGlobal.java (android\frameworks\base\core\java\android\view)
    public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
        final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams)params;

        view.setLayoutParams(wparams);

        synchronized (mLock) {
            int index = findViewLocked(view, true);
            ViewRootImpl root = mRoots.get(index);
            mParams.remove(index);
            mParams.add(index, wparams);
            root.setLayoutParams(wparams, false);
        }
    }
// ViewRootImpl.java (android\frameworks\base\core\java\android\view)
    public void setLayoutParams(WindowManager.LayoutParams attrs, boolean newView) {
...

三、测试程序

package com.example.displaycolormodetest;

import ...

public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    private static final String TAG = "lzl-test";
    private Display mDisplay;
    private ImageView mImageView;
    private TextView mTextView;
    private Button mButton_srgb;
    private Button mButton_p3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        boolean isWcgSupport = getResources().getConfiguration().isScreenWideColorGamut();
        Log.d(TAG, "getResources().getConfiguration().isScreenWideColorGamut(): " + isWcgSupport);

        mDisplay = getWindowManager().getDefaultDisplay();
        Log.d(TAG, "display.isWideColorGamut(): " + mDisplay.isWideColorGamut());

        Log.d(TAG, "display.getPreferredWideGamutColorSpace(): " + mDisplay.getPreferredWideGamutColorSpace());
        Log.d(TAG, "getWindow().getColorMode(): " + getWindow().getColorMode());

        mImageView = (ImageView)findViewById(R.id.imageView);

        getWindow().setColorMode(ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT);
        mTextView = (TextView)findViewById(R.id.textView);
        mTextView.setText("P3色域图片使用P3色域显示");
        mTextView.setTextColor(Color.RED);

        mButton_srgb = (Button)findViewById(R.id.button_srgb);
        mButton_srgb.setOnClickListener(this);
        mButton_p3 = (Button)findViewById(R.id.button_p3);
        mButton_p3.setOnClickListener(this);

        Button button_goto = (Button)findViewById(R.id.button_goto);
        button_goto.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        Button button = (Button)v;
        if (button == mButton_srgb) {
            // COLOR_MODE_DEFAULT for colorMode indicating that the activity
            // should use the default color mode (sRGB, low dynamic range).
            getWindow().setColorMode(ActivityInfo.COLOR_MODE_DEFAULT);
            mTextView.setText("P3色域图片使用sRGB色域显示");
            Log.d(TAG, "getWindow().getColorMode(): " + getWindow().getColorMode());
        } else if (button == mButton_p3) {
            // COLOR_MODE_WIDE_COLOR_GAMUT of colorMode indicating that the activity
            // should use a wide color gamut if the presentation display supports it.
            getWindow().setColorMode(ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT);
            mTextView.setText("P3色域图片使用P3色域显示");
            Log.d(TAG, "getWindow().getColorMode(): " + getWindow().getColorMode());
        } else {
            Log.e(TAG, "Unknown button id!");
        }
    }
}

使用xiaomi 13 Ultra运行

 使用adb shell dumpsys SurfaceFlinger --wide-color命令确认当前的Display color mode:

 使用adb shell dumpsys SurfaceFlinger命令确认input layer的datespace是DISPLAY_P3:

完整源码

百度网盘链接:百度网盘 请输入提取码 提取码:test

github下载地址:

GitHub - liuzhengliang1102/AndroidStudio-LearnAppDevelopment

DisplayColorModeTest目录

点此查看Android应用开发学习笔记的完整目录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/52453.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

isp调试工具环境搭建及其介绍!

一、isp调试环境搭建&#xff1a; 后期调试isp&#xff0c;是在rv1126提供的RKISP2.x Tuner工具上进行调试&#xff0c;所以我们大前提必须要把这个环境和一些操作先搞熟悉来&#xff0c;后面有一些专用术语&#xff0c;我们遇到了再去看&#xff0c;现在专门看一些专用术语&am…

Linux 多线程并发Socket服务端的实现( 11 ) -【Linux通信架构系列 】

系列文章目录 C技能系列 Linux通信架构系列 C高性能优化编程系列 深入理解软件架构设计系列 高级C并发线程编程 设计模式系列 期待你的关注哦&#xff01;&#xff01;&#xff01; 现在的一切都是为将来的梦想编织翅膀&#xff0c;让梦想在现实中展翅高飞。 Now everythi…

如何在Linux系统中安装ActiveMQ

1、环境 ActiveMQ是一个纯Java程序&#xff0c;这里安装5.18.2版ActiveMQ&#xff0c;该版MQ运行在JDK 11环境内&#xff0c;为此需要先搭建JDK 11环境&#xff0c;这里安装JDK 15。 1.1、卸载 卸载开源JDK软件包&#xff0c;如下所示&#xff1a; [rootlocalhost ~]# rpm -…

2024考研408-计算机网络 第二章-物理层学习笔记

文章目录 前言一、通信基础1.1、物理层基本概念1.1.1、认识物理层1.1.2、认识物理层的四种接口特性 1.2、数据通信基础知识1.2.1、典型的数据通信模型及相关术语1.2.2、数据通信相关术语1.2.3、设计数据通信系统要考虑的三个问题&#xff1a;问题1&#xff1a;采用单工通信/半双…

Go语言学习查缺补漏ing Day4

Go语言学习查缺补漏ing Day4 一、掌握iota的使用 请看下面这段代码&#xff1a; package mainimport "fmt"const (a iota_bc "ReganYue"dd1e iotaf iota )func main() {fmt.Println(a, b, c, d, d1, e, f) }思考一下输出结果会是什么&#xff1f; …

【数据结构篇C++实现】- 图

友情链接&#xff1a;C/C系列系统学习目录 文章目录 &#x1f680;一、图的基本概念和术语1、有向图和无向图3、基本图和多重图4、完全图5、子图6、连通、连通图和连通分量7、强连通图、强连通分量8、生成树、生成森林9、顶点的度、入度和出度10、边的权和网11、稠密图、稀疏图…

第133页的gtk+编程例子——计算器应用改写网上的例子用gtk4编译

第133页的gtk编程例子——计算器应用改写网上的例子用gtk4编译 来源&#xff1a;《GTK的计算器》 https://blog.csdn.net/zhouzhouzf/article/details/17097999 例子程序是在gtk2.0编译的&#xff0c;之前修改许多地方才能在gtk3.0编译通过&#xff0c;如今再修改能在gtk4编译…

如何在C#中处理空值

在任何编程语言中开发应用程序时&#xff0c;经常会遇到空异常或空引用异常。空指针或空引用是指不引用有效的内存位置或对象的指针。这是一个困扰程序员已经很久的问题&#xff0c;自从程序员开始编写程序以来。空值是一个特殊的值&#xff0c;表示没有有效值可用。当将空值赋…

Appium+python自动化(二十六)- Toast提示(超详解)简介

开始今天的主题 - 获取toast提示 在日常使用App过程中&#xff0c;经常会看到App界面有一些弹窗提示&#xff08;如下图所示&#xff09;这些提示元素出现后等待3秒左右就会自动消失&#xff0c;这个和我日常生活中看到的烟花和昙花是多么的相似&#xff0c;那么我们该如何获取…

数据分析-关于指标和指标体系

一、电商指标体系 二、指标体系的作用 三、统计学中基本的分析手段

从头学前端-CSS3提升-续

CSS3 2D转换 关键字&#xff1a;transform 移动&#xff1a;沿着x,y轴移动&#xff0c;不会影响盒子的位置&#xff0c;对行内元素没有效果 div {width: 100px;height: 100px;background-color: rebeccapurple;transform: translate(100px,100px);transform: translateX(100p…

centos下安装ftp-读取目录列表失败-

1.下载安装ftp服务器端和客户端 #1.安装yum -y install vsftpdyum -y install ftp #2.修改配置文件vim /etc/vsftpd.conflocal_enablesYESwrite_enableYESanonymous_enableYESanon_mkdir_write_enableYES //允许匿名用户在FTP上创建目录anon_upload_enableYES //允许匿名用户…

【Java|golang】2500. 删除每行中的最大值

给你一个 m x n 大小的矩阵 grid &#xff0c;由若干正整数组成。 执行下述操作&#xff0c;直到 grid 变为空矩阵&#xff1a; 从每一行删除值最大的元素。如果存在多个这样的值&#xff0c;删除其中任何一个。 将删除元素中的最大值与答案相加。 注意 每执行一次操作&#…

KY222 打印日期+KY111日期差值

一、KY222题目 二、代码 #include <climits> #include <iostream> using namespace std; class Date{public:Date(int year 1,int month 2,int day 3){_year year;_month month;_day day;}int GetDay(int year ,int month);void Define(int n);public:int _yea…

【Unity2D】粒子特效

为什么要使用粒子特效 Unity 的粒子系统是一种非常强大的工具&#xff0c;可以用来创建各种各样的游戏特效&#xff0c;如火焰、烟雾、水流、爆炸等等。使用粒子特效可以使一些游戏动画更加真实或者使游戏效果更加丰富。 粒子特效的使用 在Hierarchy界面右键添加Effects->…

【分布式系统】分布式系统的8个谬误

网络可靠 对于分布式系统来说&#xff0c;网络、计算、存储是三大基石&#xff0c;系统之间进行拆分隔离之后&#xff0c;那么必定存在网络通讯&#xff0c;而网络是最不可靠的。 不管是从硬件层面还是软件层面来说&#xff0c;网络是不可靠的。&#xff08;断电、配置错误、ID…

基于FPGA的VGG16卷积神经网络加速器--WL

VGG16是一个典型的卷积神经网络&#xff0c;由13层卷积层&#xff0c;5层池化层和3层全连接层组成。且卷积层的计算时间在整个计算过程中占比极大&#xff0c;通过FPGA的并行运算可以有效的加快卷积层的计算速度。 一个卷积层可以有若干个卷积核&#xff0c;以第一层为例&#…

go学习 3、基础数据类型

3、基础数据类型 基础数据类型&#xff1a;数字、字符串、布尔型复合类型&#xff1a;数组、结构体引用类型&#xff1a;指针、切片、字典、函数、通道接口类型 3.1 整型 有符号、无符号 int8/int16/int32/int64 uint8/uint16/uint32/units 64 Unicode字符rune类型是和int32…

使用Spring Boot AOP实现日志记录

目录 介绍 1.1 什么是AOP 1.2 AOP体系与概念 AOP简单实现 2.1 新建一个SpringBoot项目&#xff0c;无需选择依赖 2.2 设置好本地Maven配置后&#xff0c;在pom.xml文件里添加添加maven依赖 2.3 创建一个业务类接口 2.4 在实体类实现接口业务 2.5 在单元测试运行结果 …

python中的单引号、双引号和多引号

目录 python中的单引号 python中的双引号 python中的多引号 三者分别在什么时候使用&#xff0c;有什么区别 总结 python中的单引号 在Python中&#xff0c;单引号&#xff08;&#xff09;可以用来表示字符串。 可以使用单引号创建一个简单的字符串&#xff0c;例如&…