android – 了解使用ColorMatrix和ColorMatrixColorFilter来修改Drawable的色相

原地址https://codeday.me/bug/20170604/22491.html



我正在开发一个应用程序的UI,我正在尝试使用灰度图标,并允许用户将主题更改为他们选择的颜色。为了做到这一点,我试图只是应用一些ColorFilter以覆盖在drawable的顶部的颜色。我试过使用PorterDuff.Mode.MULTIPLY,它的工作几乎完全像我需要的,除了白色覆盖了颜色以及。我最理想的寻找是类似于Photoshop中的“颜色”混合模式,其中图形保持其透明度和光度,只修改图像的颜色。例如:
 在做了一些研究后,ColorMatrixColorFilter类似乎可以做我需要的,但我似乎找不到任何资源指向如何使用矩阵。它是一个4×5矩阵,但我需要知道的是我如何设计矩阵。有任何想法吗?

编辑:好吧,我发现到目前为止这是如下:

1 0 0 0 0 //red
0 1 0 0 0 //green
0 0 1 0 0 //blue
0 0 0 1 0 //alpha

其中该矩阵是单位矩阵(当应用时,不进行改变),并且数字范围从0到1(浮点数)。该矩阵将与每个像素相乘以转换为新颜色。所以这是开始对我来说模糊的地方。所以我认为每个像素将是一个1×4的矢量,其中包含用变换矩阵点缀的argb值(例如0.2,0.5,0.8,1)。因此,要使图像的红色强度加倍,您将使用一个矩阵,如:

2 0 0 0 0 
0 1 0 0 0 
0 0 1 0 0 
0 0 0 1 0 

这将给你0.4,0.5,0.8,1的向量(颜色)。从有限的测试,这似乎是这样的情况下,工作正常,但我实际上仍然结束了同样的问题(即白色获得着色)。进一步的阅读告诉我,这是因为它是在RGB值的转换,而对于色调移位,值应该首先转换为HSL值。所以可能我可以写一个类,将读取图像和转换的颜色,并重新绘制图像与新的颜色。这会创建另一个问题与StateListDrawables,因为我不知道我将如何获取每个代码和修改所有的这些,以及一个过程是多么缓慢的过程。 :/

嗯,好的,所以我想另一个问题,我会有一个矩阵是否可以用于转换RGB到另一个颜色空间与亮度信息,如实验室或HSL?如果是,我可以只是乘以该转换的矩阵,然后对THAT矩阵进行色调调整,然后将该矩阵应用为ColorFilter。

这是我用于我的游戏。这是在网站上的各种文章中找到的各个部分的汇编。信用从@see链接到原作者。
注意,可以用颜色矩阵做更多。包括反转等…

public class ColorFilterGenerator
{
    /**
 * Creates a HUE ajustment ColorFilter
 * @see http://groups.google.com/group/android-developers/browse_thread/thread/9e215c83c3819953
 * @see http://gskinner.com/blog/archives/2007/12/colormatrix_cla.html
 * @param value degrees to shift the hue.
 * @return
 */
public static ColorFilter adjustHue( float value )
{
    ColorMatrix cm = new ColorMatrix();

    adjustHue(cm, value);

    return new ColorMatrixColorFilter(cm);
}

/**
 * @see http://groups.google.com/group/android-developers/browse_thread/thread/9e215c83c3819953
 * @see http://gskinner.com/blog/archives/2007/12/colormatrix_cla.html
 * @param cm
 * @param value
 */
public static void adjustHue(ColorMatrix cm, float value)
{
    value = cleanValue(value, 180f) / 180f * (float) Math.PI;
    if (value == 0)
    {
        return;
    }
    float cosVal = (float) Math.cos(value);
    float sinVal = (float) Math.sin(value);
    float lumR = 0.213f;
    float lumG = 0.715f;
    float lumB = 0.072f;
    float[] mat = new float[]
    { 
            lumR + cosVal * (1 - lumR) + sinVal * (-lumR), lumG + cosVal * (-lumG) + sinVal * (-lumG), lumB + cosVal * (-lumB) + sinVal * (1 - lumB), 0, 0, 
            lumR + cosVal * (-lumR) + sinVal * (0.143f), lumG + cosVal * (1 - lumG) + sinVal * (0.140f), lumB + cosVal * (-lumB) + sinVal * (-0.283f), 0, 0,
            lumR + cosVal * (-lumR) + sinVal * (-(1 - lumR)), lumG + cosVal * (-lumG) + sinVal * (lumG), lumB + cosVal * (1 - lumB) + sinVal * (lumB), 0, 0, 
            0f, 0f, 0f, 1f, 0f, 
            0f, 0f, 0f, 0f, 1f };
    cm.postConcat(new ColorMatrix(mat));
}

protected static float cleanValue(float p_val, float p_limit)
{
    return Math.min(p_limit, Math.max(-p_limit, p_val));
}
}

要完成这个我应该添加一个例子:

ImageView Sun = (ImageView)findViewById(R.id.sun);
Sun.setColorFilter(ColorFilterGenerator.adjustHue(162)); // 162 degree rotation
http://stackoverflow.com/questions/4354939/understanding-the-use-of-colormatrix-and-colormatrixcolorfilter-to-modify-a-draw

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:android – 了解使用ColorMatrix和ColorMatrixColorFilter来修改Drawable的色相


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值