Android 中动态提取图片中颜色作为主题色
功能需求
一个页面中顶部显示一张图片(图片从网络加载),此时需要根据图片的颜色来动态调整顶部标题栏的背景色。
技术要求
Android 调色板支持库
实现过程
1、添加调色板支持库
dependencies{implementation 'androidx.palette:palette:1.0.0'}
2、创建调色板实例
这里有 2 中方式来创建
/** * 同步方式 */fun createPaletteSync(bitmap: Bitmap): Palette = Palette.from(bitmap).generate()/** * 异步方式 */ fun createPaletteAsync(bitmap: Bitmap) { Palette.from(bitmap) .generate { palette -> //TODO(业务逻辑) } }
3、获取颜色
调色板为我们提供了 6 颜色的配置文件,分别为
Light Vibrant
Vibrant
Dark Vibrant
Light Muted
Muted
Dark Muted
我们可以通过 get
Palette 类还会为每个颜色配置文件生成 Palette.Swatch 对象。Palette.Swatch 对象包含该配置文件的关联颜色以及颜色的填充(以像素为单位),通过 bodyTextColor 和 titleTextColor 及 rgb 来获取相应颜色。例如:Light Vibrant 为 palette?.lightVibrantSwatch。
如下示例通过获取图片中颜色来改变标题栏背景
fun createPaletteAsync(bitmap: Bitmap) { Palette.from(bitmap) .generate { palette -> val defaultColor = ContextCompat.getColor(this, R.color.colorPrimary) supportActionBar?.setBackgroundDrawable(ColorDrawable(palette?.getLightVibrantColor(defaultColor) ?: defaultColor)) }}
到这里可能会有疑问,有这 6 中颜色,我用哪个颜色呢?接下来介绍创建一个自定义的调色板
以下内容来自官网
使用 Palette.Builder,您可以自定义调色板,包括选择生成的调色板中的颜色数量、生成工具生成调色板所使用的图片的区域以及调色板中可以有哪些颜色。例如,您可以滤除黑色,或确保生成工具仅使用图片的上半部分来生成调色板。
使用 Palette.Builder 类中的以下方法对调色板的大小和颜色进行微调:
addFilter()
此方法会添加一个过滤器,用于指明生成的调色板中可以有哪些颜色。传入您自己的 Palette.Filter 并修改其 isAllowed() 方法,以确定从调色板中滤除哪些颜色。
maximumColorCount()
此方法可用于设置调色板中的颜色数量上限。默认值为 16,最佳值取决于源图片。对于横向显示的图片,最佳值的范围为 8 到 16,而带有人脸的图片的值通常介于 24 到 32 之间。调色板中的颜色越多,Palette.Builder 生成调色板的所用的时间就越长。
setRegion()
此方法指示在创建调色板时生成工具使用的位图的区域。您只能在从位图生成调色板时使用此方法,而且这不会影响原始图片。
addTarget()
此方法允许您通过向生成工具添加 Target 颜色配置文件来自行执行颜色调整。如果默认 Target 不够,高级开发者可以使用 Target.Builder 创建自己的 Target。
示例
fun createPaletteAsync(bitmap: Bitmap) { val filter = Palette.Filter { k, m-> k == -10448656 } val target = androidx.palette.graphics.Target.Builder() .setMaximumLightness(0.5f) .build() Palette.Builder(bitmap) .addFilter(filter)//添加过滤器,只能使用指定的某些颜色 .addTarget(target) .setRegion(0, 0, bitmap.width, (bitmap.height*0.1).toInt())//设置从某一区域中获取颜色 .generate { palette -> val defaultColor = ContextCompat.getColor(this, R.color.colorPrimary) supportActionBar?.setBackgroundDrawable(ColorDrawable(palette?.getLightVibrantColor(defaultColor) ?: defaultColor)) } }
通过上面的例子可以发现通过设置提取区域为图片的上面10%的区域 .setRegion(0, 0, bitmap.width, (bitmap.height*0.1).toInt())
至此可以基本让标题栏的颜色和图片的顶部融合的比较恰当
效果图
更多相关文章
- ListView有背景图片或背景颜色,那么在滑动ListView的时候,ListView
- Android 获取并显示远程图片 Picasso框架的使用(二)
- Android开发之实现图片自动滚动显示标签的ViewPager
- Android ListView异步加载图片乱序问题,原因分析及解决方案
- Android简单、灵活、高效的图片裁剪框架 Android-ImageClipper
- 转载关于android高效显示图片的文章---From 移动微技
- Android消息处理机制:源码剖析Handler、Looper,并实现图片异步加载
- Android常用图片加载库介绍及对比