我正在尝试创建一个Material Design的调色板,用任意颜色的十六进制来改变亮度/亮度百分比。说到实现,我发现有一些我无法生成的颜色十六进制,并显示Color Unknown Exception。您能告诉我生成这组颜色的替代方案或技术预防措施是什么?
以下是我的代码
package com.example.dino.util;
import android.content.Context;
import android.graphics.Color;
import java.util.ArrayList;
/**
* Created by larrylo on 18/1/15.
*/
public class ColorUtils {
public Context context;
public static float[] colorToHsl(String hexColor) {
int color = Color.parseColor(hexColor);
float r = ((0x00ff0000 & color) >> 16) / 255.0F;
float g = ((0x0000ff00 & color) >> 8) / 255.0F;
float b = ((0x000000ff & color)) / 255.0F;
float max = Math.max(Math.max(r, g), b);
float min = Math.min(Math.min(r, g), b);
float c = max - min;
float hTemp = 0.0F;
if (c == 0) {
hTemp = 0;
} else if (max == r) {
hTemp = (float) (g - b) / c;
if (hTemp < 0)
hTemp += 6.0F;
} else if (max == g) {
hTemp = (float) (b - r) / c + 2.0F;
} else if (max == b) {
hTemp = (float) (r - g) / c + 4.0F;
}
float h = 60.0F * hTemp;
float l = (max + min) * 0.5F;
float s;
if (c == 0) {
s = 0.0F;
} else {
s = c / (1 - Math.abs(2.0F * l - 1.0F));
}
float [] hsl = {h , s , l } ;
return hsl;
}
public static String hslToColor(int alpha, float hue, float saturation, float lightness) {
float hh = hue;
float ss = saturation;
float ll = lightness;
float h, s, v;
h = hh;
ll *= 2;
ss *= (ll <= 1) ? Ll : 2 - ll;
v = (ll + ss) / 2;
s = ((ll + ss) != 0) ? (2 * ss) / (ll + ss) : 0;
int resultColorInt = Color.HSVToColor(alpha, new float[] { h, s, v });
return Integer.toHexString(resultColorInt).toUpperCase();
}
public static ArrayList<String> returnMaterialDesignColorSet (String colorHex){
ArrayList<String> resultList = new ArrayList<String>();
float [] baseColorHSL = colorToHsl(colorHex);
double randomMid = randomWithRange(0.48 , 0.52);
String baseColor = hslToColor(1 ,baseColorHSL[0] , baseColorHSL[1] , (float)0.5);
resultList.add(baseColor);
return resultList;
}
public static double randomWithRange(double min, double max)
{
double range = Math.abs(max - min);
return (Math.random() * range) + (min <= max ? Min : max);
}
public static int colorInt (String hex){
return Color.parseColor(hex);
}
}
测试代码
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
double max = 0.52;
double min = 0.48;
double range = Math.abs(max - min);
double value = (Math.random() * range) + (min <= max ? Min : max);
float result = (float)value;
System.out.println(result);
String test = "#973f5c";
String test2 = ColorUtils.returnMaterialDesignColorSet(test).get(0);
int colorInt = ColorUtils.colorInt(test2);
actionBar .setBackgroundDrawable(new ColorDrawable(colorInt));
答案 0 :(得分:6)
原始问题
您的代码在使用颜色格式时出错。
替换hslToColor()
的最后一行,如下所示,您将使其无误地运行:
public static String hslToColor(int alpha, float hue, float saturation, float lightness) {
...
// !!! ERROR WAS ON THE LAST LINE:
return String.format("#%08x", resultColorInt).toUpperCase();
}
我测试了它 - 它的工作原理 - 因为它增加了两件事:
1)格式值为8位数
2)添加“#”前缀
代码中可能出现的第二个问题
alpha值可以具有从0(透明)到255(不透明)的值。如果你想要不透明图像,你应该传递255(0xFF)
现在你传递1
和我认为这是一个错误 - 因为它几乎是透明的。
所以要有不透明的颜色替换线
String baseColor = hslToColor(1 ,baseColorHSL[0] , baseColorHSL[1] , (float)0.5);
与
String baseColor = hslToColor(0xFF ,baseColorHSL[0] , baseColorHSL[1] , (float)0.5);
的附件强>
如果需要获得一组颜色 - 应该应用一点创造力
要创建色调调色板,您必须更改循环 a)饱和度或 b)亮度或 c)两者。
这是一个实现示例,它基于亮度从0.4到0.6(非包含)的10个步骤返回调色板
“实验”意味着你应该为自己找到价值。
public static ArrayList<String> returnMaterialDesignColorSet(String baseColorHex, int colorCount) {
ArrayList<String> resultList = new ArrayList<String>();
float [] baseColorHSL = colorToHsl(baseColorHex);
float lght=0.4;// initial lightness value (experimental)
float lStep=(0.6 - lght) / colorCount; // step to go up to 0.6 lightness (experimental)
for (int i = 0; i < colorCount; i++) {
String baseColor = hslToColor(1 ,baseColorHSL[0] , baseColorHSL[1] , lght);
resultList.add(baseColor);
lght += lStep;
}
return resultList;
}
答案 1 :(得分:0)
问题在于以下几行:
int resultColorInt = Color.HSVToColor(alpha, new float[] { h, s, v });
return Integer.toHexString(resultColorInt).toUpperCase();
当alpha值小于16(0xF0)时,它将只占用字符串中的一个字符:
// 1-char alpha
int resultColorInt = Color.HSVToColor(1, new float[]{340, 0.7f, 0.5f});
String result = Integer.toHexString(resultColorInt).toUpperCase();
// result == "1802644" - 7 chars, which is invalid color format
你需要通过在结果字符串的开头附加0来补偿1-char或0-char alphas(在0-15范围内):
// not the best code, but works
while (result.length() < 8) {
result = "0" + result;
}
// don't forget # to make it a legal color
result = "#" + result;
return result;
然而,最好的办法是完全避免使用字符串。而是使用ints - 它们包含具有更好性能的相同数据。为方便起见,在调试器中,您可以更改以HEX显示的整数,而不是DEC(在Android Studio中:右键单击“变量”视图,“查看为 - &gt; HEX”)。