Android Jetpack:利用Palette进行图片取色_android 提取 图片 颜色

142 阅读7分钟

color0.setBackgroundColor(palette.getDominantColor(Color.WHITE)) color0.setTextColor(palette.dominantSwatch?.bodyTextColor ?: Color.WHITE)

color1.setBackgroundColor(palette.getMutedColor(Color.WHITE)) color1.setTextColor(palette.mutedSwatch?.bodyTextColor ?: Color.WHITE)

color2.setBackgroundColor(palette.getDarkMutedColor(Color.WHITE)) color2.setTextColor(palette.darkMutedSwatch?.bodyTextColor ?: Color.WHITE)

color3.setBackgroundColor(palette.getLightMutedColor(Color.WHITE)) color3.setTextColor(palette.lightMutedSwatch?.bodyTextColor ?: Color.WHITE)

color4.setBackgroundColor(palette.getVibrantColor(Color.WHITE)) color4.setTextColor(palette.vibrantSwatch?.bodyTextColor ?: Color.WHITE)

color5.setBackgroundColor(palette.getDarkVibrantColor(Color.WHITE)) color5.setTextColor(palette.darkVibrantSwatch?.bodyTextColor ?: Color.WHITE)

color6.setBackgroundColor(palette.getLightVibrantColor(Color.WHITE)) color6.setTextColor(palette.lightVibrantSwatch?.bodyTextColor ?: Color.WHITE)


这样每个颜色上的文字都可以清晰的显示。


那么这个标题和主体文本颜色有什么差别,他们又是如何的到的?我们来看看源码:



/**

  • Returns an appropriate color to use for any 'title' text which is displayed over this
  • {@link Swatch}'s color. This color is guaranteed to have sufficient contrast. */ @ColorInt public int getTitleTextColor() { ensureTextColorsGenerated(); return mTitleTextColor; }

/**

  • Returns an appropriate color to use for any 'body' text which is displayed over this
  • {@link Swatch}'s color. This color is guaranteed to have sufficient contrast. */ @ColorInt public int getBodyTextColor() { ensureTextColorsGenerated(); return mBodyTextColor; }

可以看到都会先执行`ensureTextColorsGenerated()`,它的源码如下:



private void ensureTextColorsGenerated() { if (!mGeneratedTextColors) { // First check white, as most colors will be dark final int lightBodyAlpha = ColorUtils.calculateMinimumAlpha( Color.WHITE, mRgb, MIN_CONTRAST_BODY_TEXT); final int lightTitleAlpha = ColorUtils.calculateMinimumAlpha( Color.WHITE, mRgb, MIN_CONTRAST_TITLE_TEXT);

    if (lightBodyAlpha != -1 && lightTitleAlpha != -1) {
        // If we found valid light values, use them and return
        mBodyTextColor = ColorUtils.setAlphaComponent(Color.WHITE, lightBodyAlpha);
        mTitleTextColor = ColorUtils.setAlphaComponent(Color.WHITE, lightTitleAlpha);
        mGeneratedTextColors = true;
        return;
    }

    final int darkBodyAlpha = ColorUtils.calculateMinimumAlpha(
            Color.BLACK, mRgb, MIN_CONTRAST_BODY_TEXT);
    final int darkTitleAlpha = ColorUtils.calculateMinimumAlpha(
            Color.BLACK, mRgb, MIN_CONTRAST_TITLE_TEXT);

    if (darkBodyAlpha != -1 && darkTitleAlpha != -1) {
        // If we found valid dark values, use them and return
        mBodyTextColor = ColorUtils.setAlphaComponent(Color.BLACK, darkBodyAlpha);
        mTitleTextColor = ColorUtils.setAlphaComponent(Color.BLACK, darkTitleAlpha);
        mGeneratedTextColors = true;
        return;
    }

    // If we reach here then we can not find title and body values which use the same
    // lightness, we need to use mismatched values
    mBodyTextColor = lightBodyAlpha != -1
            ? ColorUtils.setAlphaComponent(Color.WHITE, lightBodyAlpha)
            : ColorUtils.setAlphaComponent(Color.BLACK, darkBodyAlpha);
    mTitleTextColor = lightTitleAlpha != -1
            ? ColorUtils.setAlphaComponent(Color.WHITE, lightTitleAlpha)
            : ColorUtils.setAlphaComponent(Color.BLACK, darkTitleAlpha);
    mGeneratedTextColors = true;
}

}


通过代码可以看到,这两种文本颜色实际上要么是白色要么是黑色,只是透明度Alpha不同。


这里面有一个关键函数,即`ColorUtils.calculateMinimumAlpha()`

public static int calculateMinimumAlpha(@ColorInt int foreground, @ColorInt int background, float minContrastRatio) { if (Color.alpha(background) != 255) { throw new IllegalArgumentException("background can not be translucent: #" + Integer.toHexString(background)); }

// First lets check that a fully opaque foreground has sufficient contrast
int testForeground = setAlphaComponent(foreground, 255);
double testRatio = calculateContrast(testForeground, background);
if (testRatio < minContrastRatio) {
    // Fully opaque foreground does not have sufficient contrast, return error
    return -1;
}

// Binary search to find a value with the minimum value which provides sufficient contrast
int numIterations = 0;
int minAlpha = 0;
int maxAlpha = 255;

while (numIterations <= MIN_ALPHA_SEARCH_MAX_ITERATIONS &&
        (maxAlpha - minAlpha) > MIN_ALPHA_SEARCH_PRECISION) {
    final int testAlpha = (minAlpha + maxAlpha) / 2;

    testForeground = setAlphaComponent(foreground, testAlpha);
    testRatio = calculateContrast(testForeground, background);

    if (testRatio < minContrastRatio) {
        minAlpha = testAlpha;
    } else {
        maxAlpha = testAlpha;
    }

    numIterations++;
}

// Conservatively return the max of the range of possible alphas, which is known to pass.
return maxAlpha;

}


它根据背景色和前景色计算前景色最合适的Alpha。这期间如果小于minContrastRatio则返回-1,说明这个前景色不合适。而标题和主体文本的差别就是这个minContrastRatio不同而已。


回到`ensureTextColorsGenerated`代码可以看到,先根据当前色调,计算出白色前景色的Alpha,如果两个Alpha都不是-1,就返回对应颜色;否则计算黑色前景色的Alpha,如果都不是-1,返回对应颜色;否则标题和主体文本一个用白色一个用黑色,返回对应颜色即可。


## 更多功能


上面我们创建Palette时先通过`Palette.from(bitmap)`的到了一个Palette.Builder对象,通过这个builder可以实现更多功能,比如:


* addFilter:增加一个过滤器
* setRegion:设置图片上的提取区域
* maximumColorCount:调色板的最大颜色数


等等


## 总结


通过上面我们看到,Palette的功能很强大,但是它使用起来非常简单,可以让我们很方便的提取图片中的颜色,并且适配合适的文字颜色。同时注意因为ColorUtils是public的,所以当我们需要文字自动适配颜色的情况时,也可以通过ColorUtils的几个函数自己实现计算动态颜色的方案。


### 文末


要想成为架构师,那就不要局限在编码,业务,要会选型、扩展,提升编程思维。此外,良好的职业规划也很重要,学习的习惯很重要,但是最重要的还是要能持之以恒,任何不能坚持落实的计划都是空谈。


如果你没有方向,这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》,帮大家将杂乱、零散、碎片化的知识进行体系化的整理,让大家系统而高效地掌握Android开发的各个知识点。  
 ![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/854e2721fd2d4769941f4f6e283dbe95~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDY4Mzc0MTQxMzQ0:q75.awebp?rk3s=f64ab15b&x-expires=1773095989&x-signature=DtBN0LGGOs9xEwrdPK4XOVx4CLU%3D)  
 相对于我们平时看的碎片化内容,这份笔记的知识点更系统化,更容易理解和记忆,是严格按照知识体系编排的。


#### 一、架构师筑基必备技能


1、深入理解Java泛型  
 2、注解深入浅出  
 3、并发编程  
 4、数据传输与序列化  
 5、Java虚拟机原理  
 6、高效IO  
 ……


![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/cd1997caf70c4d01beff55e2bc758058~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDY4Mzc0MTQxMzQ0:q75.awebp?rk3s=f64ab15b&x-expires=1773095989&x-signature=IcVdHEYok5RhC%2Fa6O30MJrCH7L4%3D)


#### 二、Android百大框架源码解析


1.Retrofit 2.0源码解析  
 2.Okhttp3源码解析  
 3.ButterKnife源码解析  
 4.MPAndroidChart 源码解析  
 5.Glide源码解析  
 6.Leakcanary 源码解析  
 7.Universal-lmage-Loader源码解析  
 8.EventBus 3.0源码解析  
 9.zxing源码分析  
 10.Picasso源码解析  
 11.LottieAndroid使用详解及源码解析  
 12.Fresco 源码分析——图片加载流程


![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/728e78cc1b5b4db8ae1f24295b1cf558~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDY4Mzc0MTQxMzQ0:q75.awebp?rk3s=f64ab15b&x-expires=1773095989&x-signature=q6tuJzNEfV8ilKqEnKg4g8%2F2IH4%3D)


#### 三、Android性能优化实战解析


* 腾讯Bugly:对字符串匹配算法的一点理解
* 爱奇艺:安卓APP崩溃捕获方案——xCrash
* 字节跳动:深入理解Gradle框架之一:Plugin, Extension, buildSrc
* 百度APP技术:Android H5首屏优化实践
* 支付宝客户端架构解析:Android 客户端启动速度优化之「垃圾回收」
* 携程:从智行 Android 项目看组件化架构实践
* 网易新闻构建优化:如何让你的构建速度“势如闪电”?
* …


![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/03c981ff259d4c98a34fc9d867eac65f~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDY4Mzc0MTQxMzQ0:q75.awebp?rk3s=f64ab15b&x-expires=1773095989&x-signature=067YXE8%2BdHIonmfDTg%2B%2FvBn%2Fxec%3D)


#### 四、高级kotlin强化实战


1、Kotlin入门教程  
 2、Kotlin 实战避坑指南  
 3、项目实战《Kotlin Jetpack 实战》


* 从一个膜拜大神的 Demo 开始
* Kotlin 写 Gradle 脚本是一种什么体验?
* Kotlin 编程的三重境界
* Kotlin 高阶函数
* Kotlin 泛型
* Kotlin 扩展
* Kotlin 委托
* 协程“不为人知”的调试技巧
* 图解协程:suspend


![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/33d265c2a0c6497bb9aaf05d29e20c57~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDY4Mzc0MTQxMzQ0:q75.awebp?rk3s=f64ab15b&x-expires=1773095989&x-signature=v7MEruW5suMR%2F2y9tb5kBkFKnPg%3D)


#### 五、Android高级UI开源框架进阶解密


1.SmartRefreshLayout的使用  
 2.Android之PullToRefresh控件源码解析  
 3.Android-PullToRefresh下拉刷新库基本用法  
 4.LoadSir-高效易用的加载反馈页管理框架  
 5.Android通用LoadingView加载框架详解  
 6.MPAndroidChart实现LineChart(折线图)  
 7.hellocharts-android使用指南  
 8.SmartTable使用指南  
 9.开源项目android-uitableview介绍  
 10.ExcelPanel 使用指南  
 11.Android开源项目SlidingMenu深切解析  
 12.MaterialDrawer使用指南  
 ![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/7c4361c01026421ea775c9779e7d643b~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDY4Mzc0MTQxMzQ0:q75.awebp?rk3s=f64ab15b&x-expires=1773095989&x-signature=g0wK6D3ByN2l1j%2FSVx4xly0riCU%3D)


#### 六、NDK模块开发


1、NDK 模块开发  
 2、JNI 模块  
 3、Native 开发工具  
 4、Linux 编程  
 5、底层图片处理  
 6、音视频开发  
 7、机器学习


![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/0adc0a0dfd8b426eada4f0529b54098c~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDY4Mzc0MTQxMzQ0:q75.awebp?rk3s=f64ab15b&x-expires=1773095989&x-signature=KVqj52tkc8WGAKOntR7MS3%2Boh%2Bk%3D)


#### 七、Flutter技术进阶


1、Flutter跨平台开发概述  
 2、Windows中Flutter开发环境搭建  
 3、编写你的第一个Flutter APP  
 4、Flutter开发环境搭建和调试  
 5、Dart语法篇之基础语法(一)  
 6、Dart语法篇之集合的使用与源码解析(二)  
 7、Dart语法篇之集合操作符函数与源码分析(三)  
 …  
 ![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/96fa5a765bcc45129d21c4f3d1d229fd~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDY4Mzc0MTQxMzQ0:q75.awebp?rk3s=f64ab15b&x-expires=1773095989&x-signature=VRXgglQnakkN0fMIkpQdXAUWhb4%3D)


#### 八、微信小程序开发


1、小程序概述及入门  
 2、小程序UI开发  
 3、API操作  
 4、购物商场项目实战……


![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/98ea46fcde0f4eb89267e8811d95b37b~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDY4Mzc0MTQxMzQ0:q75.awebp?rk3s=f64ab15b&x-expires=1773095989&x-signature=2pwPXHi7Rd7uqJ2uXqH7zuILCn0%3D)


#### 全套视频资料:


**一、面试合集**  
 ![在这里插入图片描述](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/ad824e6af61c4506ad66f44c70e51369~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDY4Mzc0MTQxMzQ0:q75.awebp?rk3s=f64ab15b&x-expires=1773095989&x-signature=P0hrtcWD2Gfq4excDp0nEeY2k%2BQ%3D)  
### 尾声

以薪资待遇为基础,以发展为最终目标,要在高薪资的地方,谋求最好的发展!

下面是有几位Android行业大佬对应上方技术点整理的一些进阶资料。有**[Android架构视频+BATJ面试专题PDF+核心笔记等资料](https://github.com/a120464/Android-P7/blob/master/Android%E5%BC%80%E5%8F%91%E4%B8%8D%E4%BC%9A%E8%BF%99%E4%BA%9B%EF%BC%9F%E5%A6%82%E4%BD%95%E9%9D%A2%E8%AF%95%E6%8B%BF%E9%AB%98%E8%96%AA%EF%BC%81.md)**。希望能够帮助到大家提升技术。如果大家想要获取的话,可以**私信我【666】免费获取哦**

![](https://p3-xtjj-sign.byteimg.com/tos-cn-i-73owjymdk6/9dc601789c1b4a4f8e8f22913a25e4d3~tplv-73owjymdk6-jj-mark-v1:0:0:0:0:5o6Y6YeR5oqA5pyv56S-5Yy6IEAg55So5oi3MDY4Mzc0MTQxMzQ0:q75.awebp?rk3s=f64ab15b&x-expires=1773095989&x-signature=I6z4RvA1XpZo7CL4UvDT7Xdb7ok%3D)