动态创建不同亮度的颜色

时间:2010-03-01 10:38:19

标签: java gwt colors

我有一种颜色,我只在运行时知道。使用这种颜色我想创建两种新颜色,一种是非常明亮的颜色,另一种是非颜色的颜色。

所以要澄清,说我有红色;我想为“浅红色”颜色和“深红色”颜色创建十六进制值。

我将如何做到这一点?我的代码是用Java编写的。

5 个答案:

答案 0 :(得分:18)

将颜色转换为HSB / HSV(色相饱和度 - 亮度/值)空间,并将亮度调高为亮,向下调整为暗。然后再转换回来。在Java中:

    import java.awt.Color;

    float hsbVals[] = Color.RGBtoHSB( originalColour.getRed(),
                                       originalColour.getGreen(),
                                       originalColour.getBlue(), null );
    Color highlight = Color.getHSBColor( hsbVals[0], hsbVals[1], 0.5f * ( 1f + hsbVals[2] ));
    Color shadow = Color.getHSBColor( hsbVals[0], hsbVals[1], 0.5f * hsbVals[2] );

HSB空间专为此类操作而设计。

关键点在于,您只需要改变亮度项即可获得所需的闪电/变暗效果。你必须试验你减轻/变暗的程度。

上面的代码将亮度转换为白色的高亮部分,中间部分转换为黑色的阴影。 (我使用此代码在按钮上创建突出显示的边框效果。)

请参阅:http://en.wikipedia.org/wiki/HSL_and_HSVhttp://www.acasystems.com/en/color-picker/faq-hsb-hsv-color.htm

编辑:根据评论,java.awt.Color类不能在GWT中使用。由于我们使用的Color类的唯一部分是HSV到RGB和RGB到HSV的转换,因为当您使用GWT时,您可以使用google来实现这些算法:Google HSV RGB conversion algorithm 。例如:

答案 1 :(得分:5)

至少有两个不错的解决方案,一个更好(不管怎么说,比另一个更合适)。这取决于你想要使用的颜色,或者是对简短代码的权衡。

使用模拟亮度的色彩空间

问题是您的颜色可能指定为RGB(即红色,绿色和蓝色的数量,反映您的显示器。)更改颜色亮度的最佳方法是在不同的颜色空间中指定颜色,其中亮度为一个组件,如HSB - 色调('颜色'),饱和度('颜色'的数量)和亮度(不言自明,我想!)

这个Wikipedia article on HSL and HSV color models解释的远不止你想知道的那样:)

查看this HSB demo

关键是,一旦您的颜色指定在一个组件亮度的不同空间中,更改亮度很容易,因为您可以根据需要增加或减少该组件,就像增加或减少数量一样RGB颜色的蓝色。我认为Java内置了一些颜色转换功能 - 一些谷歌搜索找到了this page with a handy example of Color.RGBtoHSB()并再次使用Color.HSBtoRGB

与白色或黑色混合

这很容易,但在大多数情况下都很有效,而且我编写的大多数代码需要获得两种版本的颜色(例如,对于渐变),对于像UI背景这样不重要的东西使用这种方法。逻辑是,颜色越接近白色(RGB 255,255,255),颜色越亮,越接近黑色(RGB 0,0,0)越暗。因此,为了提亮一些东西,请用25%的白色混合。对于每个通道/组件,您可以通过采用一种颜色的比例和另一种颜色的反比来混合两种颜色。

以下是未经测试的,是我用来做同样事情的Delphi代码的转换(代码来自内存,最重要的是我多年没有使用Java而且不记得了语法和类很好,所以我不希望这个编译,但你应该能够得到一个想法):

Color Blend(Color clOne, Color clTwo, float fAmount) {
    float fInverse = 1.0 - fAmount;

    // I had to look up getting colour components in java.  Google is good :)
    float afOne[] = new float[3];
    clOne.getColorComponents(afOne);
    float afTwo[] = new float[3]; 
    clTwo.getColorComponents(afTwo);    

    float afResult[] = new float[3];
    afResult[0] = afOne[0] * fAmount + afTwo[0] * fInverse;
    afResult[1] = afOne[1] * fAmount + afTwo[1] * fInverse;
    afResult[2] = afOne[2] * fAmount + afTwo[2] * fInverse;

    return new Color (afResult[0], afResult[1], afResult[2]);
}

你可能会像以下一样使用它:

Color clBrighter = Blend(Color.red, Color.white, 0.25);

您可能需要添加一些安全代码,例如确保每个组件的钳位在0..255之间,或检查dAmount是否真正在0..1范围内。

Java Color documentation看起来像Color类有各种有用的方法。 (编辑:我刚注意到你说你正在使用gwt而不是awt - 我没有使用它,也不知道标准Java中包含哪些类。这应该指向正确的方向无论如何。)这可能不是Java中最干净的方式 - 这可能是由于我现在对类和方法缺乏了解 - 但它应该足以让你顺利进入。希望有所帮助!

答案 2 :(得分:2)

我不知道你有多少颜色(我试着看看GWT是否使用了颜色......但是他们非常依赖CSS而没有特定的属性)。

无论如何,如果每个组件都有一个值(红色,绿色,蓝色),并且每个值的范围在0到255之间 - 这是标准的 - 那么应用此算法:

  • 表示每个组件
    • 将原始值乘以一个因子(假设为1.1,亮度增加10%)
    • 将float / double值转换为int
    • 如果此值超过255,则将其剪切为255

然后你会有一个新的颜色(一个新的三元组元组)。

Hexa颜色

如果您有网络格式的颜色:

RRGGBB

RR - two hexa digits for red
GG - two hexa digits for green
BB - two hexa digits for blue

你需要将它们转换为int并返回到hexa:

Hexa string to int

Integer.parseInt("AB", 16"); // returns 171

int到Hexa字符串

Integer.toHexaString(171); // returns "AB"

答案 3 :(得分:2)

由于您使用的是GWT,因此您应该使用HSL而不是RGB进行颜色计算,因为它更直观,并且可以直接应用于样式颜色。

您的初始颜色为“红色”定义为“颜色:hsl(0,100%,50%)”,有关样式颜色的更多信息,请参阅http://www.w3.org/TR/css3-color/#hsl-color

要获得浅红色,您只需要增加L(亮度)分量,因此浅红色将是“颜色:hsl(0,100%,75%)”。要获得深红色,减少L分量,“颜色:hsl(0,100%,25%)”

要应用颜色,只需使用

设置颜色即可
      component.getElement().getStyle().setColor("hsl(0,100%, 25%)")

答案 4 :(得分:0)

只需在代码中添加以下功能即可。它将根据您的要求返回更浅和更深颜色的哈希值。

传递两个参数。 (1)所选颜色的哈希值。 (2)你想要多少或更暗(例如,如果你想要10%的浅色调然后通过0.1作为第二个参数,如果你想要40%更暗然后通过-0.4(更暗的负值)作为第二个参数)< / p>

因此,如果您想要找到20%的红色阴影,请按以下方式调用 String lightred=convert("ff0000",0.2);

public static String convert(String hex, double num) {
    String rgb = "#",temp;
    int i;
    double c,cd;
    for (i = 0; i < 3; i++) {
        c = Integer.parseInt(hex.substring(i * 2,(i*2)+2), 16);
        c = Math.min(Math.max(0, c+(255*num)), 255);
        cd=c-(int)c;
        if(cd>0){c=(int)c+1;}
        temp = Integer.toHexString((int)c);
        if(temp.length()<2)
        {
            temp=temp+temp;
        }
        rgb += temp;
    }
    return rgb;
}