原地址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的色相