了解嘉洛斯和ColorMatrixColorFilter的使​​用它修改可绘制的色相 [英] Understanding the Use of ColorMatrix and ColorMatrixColorFilter to Modify a Drawable's Hue

查看:271
本文介绍了了解嘉洛斯和ColorMatrixColorFilter的使​​用它修改可绘制的色相的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我工作的一个应用程序的UI,而我试图使用灰度图标,并允许用户更改主题,以自己选择的颜色。要做到这一点,我想只是采用某种形式的ColorFilter叠加在绘制顶部的颜色。我已经使用PorterDuff.Mode.MULTIPLY审判,它的工作原理几乎完全为我所需要的,所不同的是白人得到叠加的颜色为好。我所理想地寻找的是类似的色彩混合模式在Photoshop,其中该图形保留其透明性和发光度,并且仅修改图像的颜色。例如:

成为替代文字

之后做一些研究,看来,ColorMatrixColorFilter类可以做什么,我需要的,但我似乎无法找到指向如何矩阵使用的任何资源。这是一个4x5的矩阵,但我需要知道的是我如何去设计矩阵。任何想法?

I'm working on a UI for an app, and I'm attempting to use grayscale icons, and allow the user to change the theme to a color of their choosing. To do this, I'm trying to just apply a ColorFilter of some sort to overlay a color on top of the drawable. I've tried using PorterDuff.Mode.MULTIPLY, and it works almost exactly as I need, except that whites get overlayed with the color as well. What I'm ideally looking for is something like the "Color" blending mode in Photoshop, where the graphic retains its transparency and luminosity, and only modifies the color of the image. For example:

becomes

After doing some research, it appears that the ColorMatrixColorFilter class may do what I need, but I can't seem to find any resources pointing to how the matrix is used. It's a 4x5 matrix, but what I need to know is how I go about designing the matrix. Any ideas?

编辑:那么好吧,我已经发现迄今在此如下:

So okay, what I've found so far on this is as follows:

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(浮子)。这个矩阵将每个像素乘以转换为新的颜色。因此,这是它开始变得模糊了我。所以,我觉得每个像素将包含ARGB值的1×4载体(如 0.2,0.5,0.8,1 ),将与变换矩阵加以点缀。所以要加倍图像的红色强度,你可以使用一个矩阵,如:

Where this matrix is the identity matrix (when applied, makes no changes), and the numbers range from 0 to 1 (floats). This matrix will be multiplied with each pixel to convert to the new color. So this is where it starts to get fuzzy for me. So I would think each pixel would be a 1 x 4 vector containing the argb values (e.g. 0.2, 0.5, 0.8, 1) that would be dotted with the transformation matrix. So to double the red intensity of an image, you would use a matrix such as:

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,因为我不知道我怎么会去获得所有这些在code和修改所有这些,以及它是如何缓慢的一个过程。 :/

which would give you a vector (color) of 0.4, 0.5, 0.8, 1. From limited testing, this seems to be the case, and works properly, but I actually still end up with the same problem (i.e. whites gain coloring). Further reading tells me that this is because it's doing the conversion on RGB values, whereas for hue shifting, the values should first be converted to HSL values. So possibly I could write a class that would read the image and convert the colors, and redraw the image with the new colors. This creates ANOTHER problem with StateListDrawables, as I'm not sure how I would go about getting each of these in code and modifying all of them, and how slow a process it would be. :/

嗯,好吧,我想另外一个问题,我本来就是一个矩阵是否可用于RGB转换为具有亮度信息的另一种色彩空间,如L * A * B或HSL?如果是的话,我可能只是乘矩阵为converstion,然后进行色彩调整到矩阵,然后应用矩阵的ColorFilter。

Hmm, okay, so I suppose another question I would have is whether a matrix can be used to convert RGB to another color space with luminosity information, such as L*a*b or HSL? If so, I could just multiply the matrix for that converstion, then make the hue adjustment to THAT matrix, then apply that matrix as the ColorFilter.

推荐答案

这是我用我的比赛。这是各部分对网站上的各种物品中发现的汇编。积分去从@see联系原作者。 需要注意的是很多事情可以用彩色矩阵来完成。包括反相,等...

This is what I use for my game. This is the compilation of various part found on various articles on websites. Credits goes to the original author from the @see links. Note that a lot more can be done with color matrices. Including inverting, etc...

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));
}
}

要完成此我要补充一个例子:

To complete this I should add an example:

ImageView Sun = (ImageView)findViewById(R.id.sun);
Sun.setColorFilter(ColorFilterGenerator.adjustHue(162));

这篇关于了解嘉洛斯和ColorMatrixColorFilter的使​​用它修改可绘制的色相的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆