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<Profile>Color() 来获取,例如 Light Vibrant 为 getLightVibrantColor(defaultColor),方法里要传一个默认的颜色,因为可能为空。

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())
至此可以基本让标题栏的颜色和图片的顶部融合的比较恰当

效果图

在这里插入图片描述

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值