使用调色板(Palette)API 获取颜色

一、前言

    使用调色板 API,可以获取 Bitmap 图片中的颜色,并提供了六个主要颜色配置。可以通过 Palette API 获取图片中的颜色,然后对整个页面的UI主体风格进行设置。例如根据配图色调更改标题栏颜色、文本内容等等。

二、使用 调色板(Palette) API 选择颜色

2.1 添加 Palette API 支持

    Palette API 是一个支持库,需要在项目中添加依赖库才能使用。

dependencies {
    // support 库方案
    implementation 'com.android.support:palette-v7:28.0.0'
    
    // androidx 库方案
    implementation 'androidx.palette:palette:1.0.0'
}

注意事项:
1. support 库方案和 androix 库方案只能选择一种;
2. 在新版本的AndroidStudio中,如果targetSdkVersion 在 29 及以上时,会无法使用 support库方案。

2.2 创建调色板

    创建调色板,先通过 Bitmap 实例化一个 Palette.Builder 对象。然后可以通过 Palette.Builder 对象自定义调色板,以达到需要的效果。

2.2.1 生成调色板实例

    通过 Palette 类的的 from(Bitmap bitmap) 方法生成 Palette.Builder 实例,然后通过 Palette.Builder 实例的的 generate() 方法获取到调色板实例,generate() 方法包含同步和异步两个版本。

val bm = BitmapFactory.decodeResource(resources, R.drawable.pic)
val palette = Palette.from(bm).generate()

注意事项:如果需要为图片或者对象列表生成调色板,为了提高UI绘制效率,请使用缓存机制。

2.2.2 自定义调色板

     通过对 Palette.Builder 进行配置,可以自定义调色板,包括生成调色板的颜色数量(默认值16)、生成调色板对应的图片区域(默认全图)、调色板中可以显示哪些颜色等。Palette.Builder 类中包含以下方法可以对调色板进行微调。

  • addFilter():此方法添加一个过滤器,用于指明生成的调色板中可以有那些颜色,可以定义一个 Palette.Filter 并重写 isAllowed(int rgb, float[] hsl) 方法,该方法返回一个 boolean 类型值,true 为接受该颜色值,false 为拒绝改颜色值。
  • maximumColorCount():此方法用于设定调色板中颜色数量,默认值为16,最佳值取决于原图片,并且调色板颜色数量也可能会小于这个最大值。调色班中的颜色越多,Palette.Builder 生成调色板对象的事件就越长。
  • setRegion():这个方法指定创建调色板时针对 Bitmap 的区域。这个方法只有在从 Bitmap 生成调色板是有效,并且不会影响 Bitmap
  • addTarget():此方法允许开发者向生成工具添加 Target 颜色配置文件来执行颜色调整。如果默认的 Target.Builde 不够用,开发者还可以使用 Target.Builde 创建自己的 Target
val palette = Palette.from(bm)
    .maximumColorCount(24)
    .setRegion(50, 50, 400, 400)
    .addFilter(Palette.Filter { rgb, hsl ->
        // 这里是isAllowed() 方法,lambda表达式模式
        rgb != Color.argb(0xff, 0x28, 0x48, 0x88)
    })
    .generate()

注意事项:自定义调色板是针对 Palette.Builder 对象,必须在 generate() 方法生成 Palette 对象之前定义。

2.3 使用调色板的配置

     调色板库是用来从图片提取常用的颜色配置文件(默认有六个),每个配置文件都由 Target 定义。创建调色板对象时,调色板库会针对从位图图片中提取的颜色进行评分,具体评判标准包括饱和度、亮度和填充(由颜色表示的位图像素数),由得分最高的颜色来定义给定图片的颜色配置文件。在默认情况下,调色板对象包含 16 种主要颜色,但是可以通过自定义调色板(参考:自定义调色板)定义提取更多的颜色,已达到提高颜色配置文件的匹配。

     调色板库会尝试提取一下六个颜色配置文件,但不一定会提取成功,每个 Palette 对象的 get<Profile>Color() 方法返回与该特定配置文件相关联的调色板中的颜色(可通过 Palette 对象的 get<Profile>Swatch() 方法获取对应的颜色配置的 Palette.Swatch对象,如果获取失败,配置为 null,那么对应的配置颜色也只能返回默认颜色)。

  • Light Vibrant(亮鲜艳的):

  • Vibrant(鲜艳的):

  • Dark Vibrant(安鲜艳的):

  • Light Muted(亮柔和的):

  • Muted(柔和的):

  • Dark Muted(暗柔和的):

  • 示例

val palette = Palette.from(bm)
.generate(object: Palette.PaletteAsyncListener {
    override fun onGenerated(palette: Palette?) {
        palette?.apply {
            if(null == palette.lightVibrantSwatch) {
                tvLightVibrant.setText("未能获取到Light Vibrant颜色配置")
            } else {
                tvLightVibrant.setBackgroundColor(palette.lightVibrantSwatch!!.rgb)
                tvLightVibrant.setTextColor(palette.lightVibrantSwatch!!.bodyTextColor)
                tvLightVibrant.setText("Light Vibrant(${color2String(palette.lightVibrantSwatch!!.rgb)})")
            }
            if(null == palette.vibrantSwatch) {
                tvVibrant.setText("未能获取到Vibrant颜色配置")
            } else {
                tvVibrant.setBackgroundColor(palette.vibrantSwatch!!.rgb)
                tvVibrant.setTextColor(palette.vibrantSwatch!!.bodyTextColor)
                tvVibrant.setText("Vibrant(${color2String(palette.vibrantSwatch!!.rgb)})")
            }
            if(null == palette.darkVibrantSwatch) {
                tvDarkVibrant.setText("未能获取到Dark Vibrant颜色配置")
            } else {
                tvDarkVibrant.setBackgroundColor(palette.darkVibrantSwatch!!.rgb)
                tvDarkVibrant.setTextColor(palette.darkVibrantSwatch!!.bodyTextColor)
                tvDarkVibrant.setText("Dark Vibrant(${color2String(palette.darkVibrantSwatch!!.rgb)})")
            }

            if(null == palette.lightMutedSwatch) {
                tvLightMuted.setText("未能获取到Light Muted颜色配置")
            } else {
                tvLightMuted.setBackgroundColor(palette.lightMutedSwatch!!.rgb)
                tvLightMuted.setTextColor(palette.lightMutedSwatch!!.bodyTextColor)
                tvLightMuted.setText("Light Muted(${color2String(palette.lightMutedSwatch!!.rgb)})")
            }
            if(null == palette.mutedSwatch) {
                tvMuted.setText("未能获取到Muted颜色配置")
            } else {
                tvMuted.setBackgroundColor(palette.mutedSwatch!!.rgb)
                tvMuted.setTextColor(palette.mutedSwatch!!.bodyTextColor)
                tvMuted.setText("Muted(${color2String(palette.mutedSwatch!!.rgb)})")
            }
            if(null == palette.darkMutedSwatch) {
                tvDarkMuted.setText("未能获取到Dark Muted颜色配置")
            } else {
                tvDarkMuted.setBackgroundColor(palette.darkMutedSwatch!!.rgb)
                tvDarkMuted.setTextColor(palette.darkMutedSwatch!!.bodyTextColor)
                tvDarkMuted.setText("Dark Muted(${color2String(palette.darkMutedSwatch!!.rgb)})")
            }

            palette.swatches.forEach {
                Log.e("AAAA", color2String(it.rgb))
            }
            adapter.addDatas(palette.swatches)
        }
    }
})

在这里插入图片描述

讲解:以上示例中,提取图片中 16 种颜色(默认值),可以看到系统的六个颜色配置文件,只成功提取了三个。如果通过自定义调色板,获取更多的颜色,系统默认的六个颜色配置文件可成功提取的数量就会越多。

2.4 使用色样创建配色方案

    Palette 类会为每个颜色配置文件生成 Palette.Swatch 对象,Palette.Swatch 对象包含该配置文件的填充色及关联颜色。前面章节提到,可通过 Palette 对象的 get<Profile>Swatch() 方法获取对应的颜色配置的配色信息(上面提到的六种颜色配置文件),如果需要获取所有色样,可以使用Palette 对象的 getSwatches() 方法。

    当我们获取到特定的颜色配置之后,该颜色配置文件会包含色样颜色,以及色样颜色的标题文字颜色、正文文字等配色颜色。使用色样及这些配色,就可以实现根据图片来优化页面的配色方案了。

val palette = Palette.from(bm)
    .maximumColorCount(16)
    .generate(object : Palette.PaletteAsyncListener {
        override fun onGenerated(palette: Palette?) {
            palette?.lightVibrantSwatch?.apply {
                Log.e("XXXX", "lightVibrant: ${color2String(rgb)}")
                supportActionBar?.setBackgroundDrawable(ColorDrawable(palette.lightVibrantSwatch!!.rgb))
            }
            
            if (null != palette) {
                adapter.addDatas(palette.swatches)
            }
        }
    })
  • 实现效果
    使用射阳配置改变配色方案

三、编后语

    调色板库的作用是提取图片的色样,用于UI配色方案。例如音乐播放器需要根据封面改变播放界面的配色方案、报刊类根据配图改变配色方案等等,可以提高用户视觉体验。不过需要注意的是,获取图片颜色配置是非常耗时的操作,需要注意优化,防止程序卡顿,造成不好的用户体验。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值