android修改自动背光,自动背光算法-Android 8.1

本文基于工作中自动背光笔记扩充了下,记录下自动背光算法。

基于Android 8.1, 代码可参看 http://androidxref.com/8.1.0_...

Android 9加入了所谓的机器学习算法,根据用户调节时亮度和光感重新生成曲线,

自动背光时的滑动条不再是调节adjustment值,暂时不想写了。。。

Android 10简单看了下,加入了对foreground应用的微调支持,暂时不想写了。。。

一、简单说说

简单的说,其实背光调节就三大步,建曲线,采样去抖,计算亮度

1. 建曲线

Brightness

1 ^

|

|

| 。

| 。

| 。

+ 。

min+ 。

|

0---+---+-------------------> lux

min

建曲线这个其实就是建立一个lux对应的brightness的曲线,这样就可以根据光感传来的lux值,计算出对应的亮度为多少。

(安卓的算法需要Brightness比lux多一个值,所以上图曲线两者的min值不对应。另外需要严格单调递增,组数看需要,上图只是个示意)

2. 采样去抖

这个就是采集一段时间内的lux值,然后根据这段时间的lux,算出这段时间的lux值。

当然考虑到抖动(如有闪电等突然变化很大,然后又恢复的情况;或者周期性的明暗明暗变化等情况),所以需要去抖,

默认安卓是要求光照稳定在0.8~1.1倍之间,并且持续一段时间(由暗到亮是4秒,由亮到暗是8s)

3. 计算亮度

安卓的算法流程

1). 开自动背光时,下拉通知条为一系数,假设为x,其区间为[-1.0, 1.0], 应用层为除以1024,浮点精度

2). 计算背光时,先计算出lux对应的亮度,假设为y,其区间为[0.0, 1.0], 考虑为用户会微调,所以然后再处理用户微调(1中的x)

3). 最终计算屏幕亮度z向下取整

4). 然后再处理z的极值区间,例如我们设置的11~255, 18~255

用公式表示即为

$$

\mathbf{z = y^{3^{-x}}*255, x\in[-1.0, 1.0], y\in[0.0, 1.0], z\in[min, 255]}

$$

公式中3表示为gamma3.0,后面是3的-x次方,即$3^{-x}$

举个例子,

/

出地库 光照稳定在0.8~1.1倍之间4S /

| | |/

+---------+-----------------------+--------------

10lux 5000lux 开始改变屏幕,假设屏幕亮度从55 -> 255,

那么亮度调节完需要时间为((255-55)/rampRate)*16.6ms, 约3.3S

(16.6ms是一个vsync时间,rampRate默认为1,可以更改进行速率调节)

二、说点代码

代码分析其实基本也是按照前面的三点来说的,

1. 建曲线配置

frameworks/base/core/res/res/values/config.xml

false

曲线的配置为如上面的代码里,默认安卓是没有配置的,需要自己修改或者overlay,

另外还有个是否使用自动背光的开关 config_automatic_brightness_available,默认关的,需要打开。

代码里都有详细的注释和说明可看看,我这儿就没贴出来了。

config_autoBrightnessLevels为lux数组

config_autoBrightnessLcdBacklightValues为对应的lcd亮度值,

比lux数组多一个,组成和曲线需要严格单调递增。

config_autoBrightnessLevels -> lux

config_autoBrightnessLcdBacklightValues -> brightness

--> brightness[0]

lux[0] --> brightness[1]

lux[1] --> brightness[2]

lux[2] --> brightness[3]

.....

2. 曲线初始化

曲线设置好了,就应该扔代码里跑起来,模型建起来了,这个过程是咋样的呢?

通过搜索配置关键词(

config_automatic_brightness_available

config_autoBrightnessLevels

config_autoBrightnessLcdBacklightValues

) 或知道其在DisplayPowerController()构造的时候初始化的。

frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java

public DisplayPowerController(......) {

......

// 使能开关

mUseSoftwareAutoBrightnessConfig = resources.getBoolean(

com.android.internal.R.bool.config_automatic_brightness_available);

......

if (mUseSoftwareAutoBrightnessConfig) {

// 光感数组

int[] lux = resources.getIntArray(

com.android.internal.R.array.config_autoBrightnessLevels);

// 背光亮度数组

int[] screenBrightness = resources.getIntArray(

com.android.internal.R.array.config_autoBrightnessLcdBacklightValues);

// 其它一些配置

int lightSensorWarmUpTimeConfig = resources.getInteger(

com.android.internal.R.integer.config_lightSensorWarmupTime);

final float dozeScaleFactor = resources.getFraction(

com.android.internal.R.fraction.config_screenAutoBrightnessDozeScaleFactor,

1, 1);

// 创建自动背光样条

Spline screenAutoBrightnessSpline = createAutoBrightnessSpline(lux, screenBrightness);

if (screenAutoBrightnessSpline == null) {

// 如果lux, brightness不合要求,禁用自动背光

Slog.e(TAG, "Error in config.xml. config_autoBrightnessLcdBacklightValues "

+ "(size " + screenBrightness.length + ") "

+ "must be monotic and have exactly one more entry than "

+ "config_autoBrightnessLevels (size " + lux.length + ") "

+ "which must be strictly increasing. "

+ "Auto-brightness will be disabled.");

mUseSoftwareAutoBrightnessConfig = false;

} else {

......

mAutomaticBrightnessController = new AutomaticBrightnessController(this,

handler.getLooper(), sensorManager, screenAutoBrightnessSpline,

...// gamma, 最大最小值等其他配置

}

}

如果打开了自动背光功能,会根据lux和brightness数组,创建样条曲线(以得到一条光滑曲线,安卓采用的是三次样条插值,有兴趣的可以搜索下学习学习),

如果数组不满足要求,会禁用自动背光功能。

创建样条曲线成功后赋值给 AutomaticBrightnessController(),后面背光控制的主体逻辑就转到 AutomaticBrightnessController类里了。

AutomaticBrightnessController()构造就一些赋值,没啥可看的,重点看下 createAutoBrightnessSpline()

private static Spline createAutoBrightnessSpline(int[] lux, int[] brightness) {

......

// 归一化brightness[0]作为y[0]

y[0] = normalizeAbsoluteBrightness(brightness[0]);

// 处理对应的lux和brightness

  • 1
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值