Android 全局黑白化-模拟颜色空间

Android 全局黑白化-模拟颜色空间概述 平台 RK3568 Android 11 在一些特殊的日子 如默哀日 灾难日 纪念日 哀悼日等 许多的 APP 网页 海报等都开始使用黑白 色主题 Android 的全局黑白实现方案 可以考虑使用模拟颜色空间 的方法 借助硬件加速渲染选项

大家好,我是讯享网,很高兴认识大家。

概述

平台: RK3568 + Android 11 

讯享网

在这里插入图片描述
讯享网

     在一些特殊的日子,如默哀日、灾难日,纪念日,哀悼日等,许多的APP、网页、海报等都开始使用黑白色主题。Android 的全局黑白实现方案,可以考虑使用模拟颜色空间的方法。

在这里插入图片描述

      借助硬件加速渲染选项,您可以利用基于硬件的选项(如 GPU、硬件层和多重采样抗锯齿 (MSAA)针对目标硬件平台优化应用。

点按模拟颜色空间可以更改整个设备界面的配色方案。此设置下面的选项是指色盲类型。可选项如下:

  • 已停用(无模拟配色方案)
  • 全色盲(配色方案限于黑色、白色和灰色)
  • 绿色弱视(影响显示红色和绿色)
  • 红色弱视(影响显示红色和绿色)
  • 蓝色弱视(影响显示蓝色和黄色)

实现

     在设置的开发选项中可以找到: 设置 > 系统 > 开发者选项 > 模拟颜色空间,

文本来源

讯享网rk3568_a11$ grep -r "模拟颜色空间" frameworks/base/packages/SettingsLib/ 

frameworks/base/packages/SettingsLib/res/values-zh-rCN/strings.xml

 <string name="simulate_color_space" msgid="">"模拟颜色空间"</string> <string name="daltonizer_mode_monochromacy" msgid="">"全色盲"</string> <string name="daltonizer_mode_deuteranomaly" msgid="">"绿色弱视(红绿不分)"</string> <string name="daltonizer_mode_protanomaly" msgid="">"红色弱视(红绿不分)"</string> <string name="daltonizer_mode_tritanomaly" msgid="">"蓝色弱视(蓝黄不分)"</string> 
讯享网rk3568_a11$ grep -r "simulate_color_space" packages/apps/Settings packages/apps/Settings/tests/robotests/src/com/android/settings/development/SimulateColorSpacePreferenceControllerTest.java: mListValues = mContext.getResources().getStringArray(R.array.simulate_color_space_values); packages/apps/Settings/src/com/android/settings/development/SimulateColorSpacePreferenceController.java: private static final String SIMULATE_COLOR_SPACE = "simulate_color_space"; packages/apps/Settings/res/xml/development_settings.xml: android:entries="@array/simulate_color_space_entries" packages/apps/Settings/res/xml/development_settings.xml: android:entryValues="@array/simulate_color_space_values" packages/apps/Settings/res/xml/development_settings.xml: android:key="simulate_color_space" packages/apps/Settings/res/xml/development_settings.xml: android:title="@string/simulate_color_space" /> 

packages/apps/Settings/res/xml/development_settings.xml 开发者选项

 <ListPreference android:entries="@array/simulate_color_space_entries" android:entryValues="@array/simulate_color_space_values" android:key="simulate_color_space" android:summary="%s" android:title="@string/simulate_color_space" /> 

对应的模式的值

frameworks/base/packages/SettingsLib/res/values/arrays.xml

讯享网 <!-- Display color space adjustment modes for developers --> <string-array name="simulate_color_space_entries" translatable="false"> <item>@string/daltonizer_mode_disabled</item> <item>@string/daltonizer_mode_monochromacy</item> <item>@string/daltonizer_mode_deuteranomaly</item> <item>@string/daltonizer_mode_protanomaly</item> <item>@string/daltonizer_mode_tritanomaly</item> </string-array> <!-- Values for display color space adjustment modes for developers --> <string-array name="simulate_color_space_values" translatable="false"> <item>-1</item> <item>0</item> <item>2</item> <item>1</item> <item>3</item> </string-array> 

修改系统设置值, 主要是使能和模式

packages/apps/Settings/src/com/android/settings/development/SimulateColorSpacePreferenceController.java

 private void writeSimulateColorSpace(Object value) { 
    final ContentResolver cr = mContext.getContentResolver(); final int newMode = Integer.parseInt(value.toString()); if (newMode < 0) { 
    Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, SETTING_VALUE_OFF); } else { 
    Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER_ENABLED, SETTING_VALUE_ON); Settings.Secure.putInt(cr, Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, newMode); } } 

服务里监听设置项变化并执行响应

frameworks/base/services/core/java/com/android/server/display/color/ColorDisplayService.java

讯享网 / * Apply the accessibility daltonizer transform based on the settings value. */ private void onAccessibilityDaltonizerChanged() { 
    if (mCurrentUser == UserHandle.USER_NULL) { 
    return; } final int daltonizerMode = isAccessiblityDaltonizerEnabled() ? Secure.getIntForUser(getContext().getContentResolver(), Secure.ACCESSIBILITY_DISPLAY_DALTONIZER, AccessibilityManager.DALTONIZER_CORRECT_DEUTERANOMALY, mCurrentUser) : AccessibilityManager.DALTONIZER_DISABLED; final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class); if (daltonizerMode == AccessibilityManager.DALTONIZER_SIMULATE_MONOCHROMACY) { 
    // Monochromacy isn't supported by the native Daltonizer implementation; use grayscale. dtm.setColorMatrix(DisplayTransformManager.LEVEL_COLOR_MATRIX_GRAYSCALE, MATRIX_GRAYSCALE); dtm.setDaltonizerMode(AccessibilityManager.DALTONIZER_DISABLED); } else { 
    dtm.setColorMatrix(DisplayTransformManager.LEVEL_COLOR_MATRIX_GRAYSCALE, null); dtm.setDaltonizerMode(daltonizerMode); } } 

frameworks/base/services/core/java/com/android/server/display/color/DisplayTransformManager.java

 private static final int SURFACE_FLINGER_TRANSACTION_DALTONIZER = 1014 / * Sets and applies a current color transform matrix for a given level. * <p> * Note: all color transforms are first composed to a single matrix in ascending order based on * level before being applied to the display. * * @param level the level used to identify and compose the color transform (low -> high) * @param value the 4x4 color transform matrix (in column-major order), or {@code null} to * remove the color transform matrix associated with the provided level */ public void setColorMatrix(int level, float[] value) { 
    if (value != null && value.length != 16) { 
    throw new IllegalArgumentException("Expected length: 16 (4x4 matrix)" + ", actual length: " + value.length); } synchronized (mColorMatrix) { 
    final float[] oldValue = mColorMatrix.get(level); if (!Arrays.equals(oldValue, value)) { 
    if (value == null) { 
    mColorMatrix.remove(level); } else if (oldValue == null) { 
    mColorMatrix.put(level, Arrays.copyOf(value, value.length)); } else { 
    System.arraycopy(value, 0, oldValue, 0, value.length); } // Update the current color transform. applyColorMatrix(computeColorMatrixLocked()); } } } / * Sets the current Daltonization mode. This adjusts the color space to correct for or simulate * various types of color blindness. * * @param mode the new Daltonization mode, or -1 to disable */ public void setDaltonizerMode(int mode) { 
    synchronized (mDaltonizerModeLock) { 
    if (mDaltonizerMode != mode) { 
    mDaltonizerMode = mode; applyDaltonizerMode(mode); } } } / * Propagates the provided Daltonization mode to the SurfaceFlinger. */ private static void applyDaltonizerMode(int mode) { 
    final Parcel data = Parcel.obtain(); data.writeInterfaceToken("android.ui.ISurfaceComposer"); data.writeInt(mode); try { 
    sFlinger.transact(SURFACE_FLINGER_TRANSACTION_DALTONIZER, data, null, 0); } catch (RemoteException ex) { 
    Slog.e(TAG, "Failed to set Daltonizer mode", ex); } finally { 
    data.recycle(); } } 

传到SurfaceFlinger

frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp

讯享网 status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { 
    //............ switch (code) { 
    case 1014: { 
    Mutex::Autolock _l(mStateLock); // daltonize n = data.readInt32(); switch (n % 10) { 
    case 1: mDaltonizer.setType(ColorBlindnessType::Protanomaly); break; case 2: mDaltonizer.setType(ColorBlindnessType::Deuteranomaly); break; case 3: mDaltonizer.setType(ColorBlindnessType::Tritanomaly); break; default: mDaltonizer.setType(ColorBlindnessType::None); break; } if (n >= 10) { 
    mDaltonizer.setMode(ColorBlindnessMode::Correction); } else { 
    mDaltonizer.setMode(ColorBlindnessMode::Simulation); } updateColorMatrixLocked(); return NO_ERROR; } //........................ 

关于 Settings > 色彩校正

实现的原理与黑白色是一样的:
在这里插入图片描述

packages/apps/Settings/res/xml/accessibility_daltonizer_settings.xml

 <PreferenceCategory android:title="@string/daltonizer_type" android:key="daltonizer_mode_category" > <com.android.settingslib.widget.RadioButtonPreference android:key="daltonizer_mode_deuteranomaly" android:persistent="false" android:summary="@string/daltonizer_mode_deuteranomaly_summary" android:title="@string/daltonizer_mode_deuteranomaly_title" /> <com.android.settingslib.widget.RadioButtonPreference android:key="daltonizer_mode_protanomaly" android:persistent="false" android:summary="@string/daltonizer_mode_protanomaly_summary" android:title="@string/daltonizer_mode_protanomaly_title" /> <com.android.settingslib.widget.RadioButtonPreference android:key="daltonizer_mode_tritanomaly" android:persistent="false" android:summary="@string/daltonizer_mode_tritanomaly_summary" android:title="@string/daltonizer_mode_tritanomaly_title" /> </PreferenceCategory> 

packages/apps/Settings/src/com/android/settings/accessibility/ToggleDaltonizerPreferenceFragment.java

讯享网 @Override protected int getPreferenceScreenResId() { 
    return R.xml.accessibility_daltonizer_settings; } 

packages/apps/Settings/src/com/android/settings/accessibility/DaltonizerRadioButtonPreferenceController.java

 private static final String TYPE = Settings.Secure.ACCESSIBILITY_DISPLAY_DALTONIZER; private void putSecureString(String name, String value) { 
    Settings.Secure.putString(mContentResolver, name, value); } private void handlePreferenceChange(String value) { 
    putSecureString(TYPE, value); } 

APP 如何调用?

     普通APP没有调用的权限, 两种调用方法:

  1. App拥有system uid
讯享网 final android.content.ContentResolver cr = context.getContentResolver(); final int newMode = on ? 0 : -1; if (newMode < 0) { 
    android.provider.Settings.Secure.putInt(cr, "accessibility_display_daltonizer_enabled", 0); } else { 
    android.provider.Settings.Secure.putInt(cr, "accessibility_display_daltonizer_enabled", 1); //public static final String ACCESSIBILITY_DISPLAY_DALTONIZER = // "accessibility_display_daltonizer"; android.provider.Settings.Secure.putInt(cr, "accessibility_display_daltonizer", newMode); } 
  1. 平台已ROOT, 执行命令
settings put secure accessibility_display_daltonizer_enabled 1 settings put secure accessibility_display_daltonizer 0 

参考

安卓APP全局黑白化实现方案
Android全局设置APP为黑白模式的两种方案
配置设备上的开发者选项

小讯
上一篇 2025-03-05 08:10
下一篇 2025-03-10 18:42

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/38991.html