java 动态创建不同亮度的颜色
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2355157/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Dynamically creating colors with different brightness
提问by user283524
I have a color, which I only know at runtime. Using this color i want to create two new colors, one very bright and one none bright version of the color.
我有一种颜色,我只在运行时知道。使用这种颜色,我想创建两种新颜色,一种非常亮的颜色,另一种不亮的颜色。
So to clarify, say i have the color Red; I want to create the hex-value for a "Light red" color, and a "Dark red" color.
所以澄清一下,假设我有红色;我想为“浅红色”颜色和“深红色”颜色创建十六进制值。
How would i go about doing this? My code is written in Java using GWT.
我该怎么做呢?我的代码是使用 GWT 用 Java 编写的。
回答by Adrian Pronk
Convert the colours to the HSB/HSV (Hue-Saturation-Brightness/Value ) space and adjust the Brightness up for lighter and down for darker. Then convert back again. In Java:
将颜色转换为 HSB/HSV (Hue-Saturation-Brightness/Value) 空间并向上调整亮度以获得更亮,向下调整为更暗。然后再转换回来。在 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] );
The HSB space is designed for this kind of operation.
HSB 空间专为此类操作而设计。
The essential point is that you only need to vary the Brightness term to get the lightening/darkening effect you want. You'll have to experiment with how much you lighten/darken.
要点是您只需要改变亮度项即可获得您想要的变亮/变暗效果。您必须尝试变亮/变暗的程度。
The above code shifts the Brightness to half-way towards white for the highlight and half-way to black for the shadow. (I used this code to create a highlighted border effect on a button.)
上面的代码将亮度移动到一半的高光白色和一半的黑色阴影。(我使用此代码在按钮上创建突出显示的边框效果。)
See: http://en.wikipedia.org/wiki/HSL_and_HSVand http://www.acasystems.com/en/color-picker/faq-hsb-hsv-color.htm
请参阅:http: //en.wikipedia.org/wiki/HSL_and_HSV和http://www.acasystems.com/en/color-picker/faq-hsb-hsv-color.htm
Edit:According to the comments, the java.awt.Colorclass can't be used in GWT. Since the only part of theColorclass we're using are the HSV to RGB and the RGB to HSV conversions, as you're using GWT you could instead google for an implementation of those algorithms: Google HSV RGB conversion algorithm. For example:
编辑:根据评论,java.awt.Color该类不能在 GWT 中使用。由于Color我们使用的类的唯一部分是 HSV 到 RGB 和 RGB 到 HSV 的转换,当您使用 GWT 时,您可以改为谷歌实现这些算法: 谷歌 HSV RGB 转换算法。例如:
回答by David
There are at least two decent solutions to this, one better (more 'proper', anyway) than the other. It depends on what you want to use the colour for, or a tradeoff against short and simple code.
至少有两个不错的解决方案,一个比另一个更好(无论如何更“合适”)。这取决于您想将颜色用于什么,或者与简短的代码进行权衡。
Using a colour space that models brightness
使用模拟亮度的色彩空间
The problem is your colours are probably specified as RGB (ie, amounts of red, green and blue, reflecting your monitor.) The best way to change a colour's brightness is to specify your colours in a different colour space where brightness is one component, such as HSB - hue (the 'colour'), saturation ('amount' of the colour) and brightness (self-explanatory, I think!)
问题是您的颜色可能被指定为 RGB(即红色、绿色和蓝色的数量,反映您的显示器。)更改颜色亮度的最佳方法是在不同的颜色空间中指定您的颜色,其中亮度是一个组成部分,例如 HSB - 色调(“颜色”)、饱和度(颜色的“数量”)和亮度(我认为不言自明!)
This Wikipedia article on HSL and HSV color modelsexplains far more than you probably want to know :)
这对HSL和HSV颜色模型Wikipedia文章解释了远远超过你可能想知道:)
Have a look at this HSB demo.
看看这个 HSB 演示。
The point is, once your colours are specified in a different space where one component is brightness, changing the brightness is easy because you can increase or decrease that component as you wish, in the same way you might increase or decrease the amount of blue in a RGB colour. Java, I think, has some colour conversion functions built in - some googling found this page with a handy example of Color.RGBtoHSB()and going back again with Color.HSBtoRGB.
关键是,一旦你的颜色被指定在一个不同的空间中,其中一个分量是亮度,改变亮度很容易,因为你可以根据需要增加或减少那个分量,就像你可以增加或减少蓝色的数量一样RGB 颜色。我认为,Java 内置了一些颜色转换功能——一些谷歌搜索发现这个页面有一个方便的例子,Color.RGBtoHSB()然后用Color.HSBtoRGB.
Blending with white or black
与白色或黑色混合
This is hackier, but effective in most situations, and most code I've written that needs to get two versions of a colour (for a gradient, for example) for something unimportant like a UI background uses this sort of method. The logic is that a colour will be brighter as it gets closer to white (RGB 255,255,255) and darker as it gets closer to black (RGB 0,0,0). So to brighten something, blend with white by, say, 25%. You can blend between two colours by taking a proportion of one colour, and the inverse of that proportion of the other, for each channel / component.
这是 hackier,但在大多数情况下有效,并且我编写的大多数代码需要为不重要的东西(如 UI 背景)获取两种颜色版本(例如渐变),使用这种方法。逻辑是颜色越接近白色 (RGB 255,255,255) 越亮,越接近黑色 (RGB 0,0,0) 越暗。因此,要使某些东西变亮,请与白色混合,例如 25%。对于每个通道/组件,您可以通过采用一种颜色的比例以及另一种颜色的比例的倒数来混合两种颜色。
The following is untested, and is a conversion of Delphi code I have used to do the same thing (the code is taken from memory, and on top of that I haven't used Java for years and don't remember the syntax and classes well, so I don't expect this to compile but you should be able to get an idea):
以下是未经测试的,是我用来做同样事情的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]);
}
And you'd probably use it like:
你可能会像这样使用它:
Color clBrighter = Blend(Color.red, Color.white, 0.25);
You might want to add some safety code, such as ensuring a clamp between 0..255 for each component, or checking that dAmountis truly in the range 0..1.
您可能想要添加一些安全代码,例如确保每个组件的钳位在 0..255 之间,或者检查它dAmount是否确实在 0..1 范围内。
The Java Color documentationlooks like the Colorclass has all sorts of useful methods. (Edit: I just noticed you said you're using gwtnot awt- I haven't used it and have no idea what classes from standard Java are included. This should point you in the right direction anyway.) It's possible this is not the cleanest way in Java - that'll be due to my lack of knowledge of the classes and methods these days - but it should be enough to get you well down the track. Hope that helps!
在Java的彩色文档看起来像Color类有各种有用的方法。(编辑:我刚才注意到你说你正在使用的gwt不是awt-我还没有使用它,而且不知道是包括从标准的Java类的东西它应该指向你在正确的方向呢。)这是可能的,这不是最干净在 Java 中的方式 - 这将是由于我现在缺乏对类和方法的了解 - 但它应该足以让你走上正轨。希望有帮助!
回答by Ivo Bosticky
Since you are using GWT, you should do your color calculations using HSL rather then RGB, as it's more intuitive, and can be applied as a style color directly to your components.
由于您使用的是 GWT,您应该使用 HSL 而不是 RGB 进行颜色计算,因为它更直观,并且可以作为样式颜色直接应用于您的组件。
Your initial color is "red" is defined as "color: hsl(0,100%, 50%)", see http://www.w3.org/TR/css3-color/#hsl-colorfor more on style colors.
您的初始颜色是“红色”,定义为“颜色:hsl(0,100%, 50%)”,有关样式颜色的更多信息,请参见http://www.w3.org/TR/css3-color/#hsl-color。
To get a light red, all you need is to increase the L (lightness) component, so a light red would be "color: hsl(0,100%, 75%)". To get a dark red, decrease the L component, "color: hsl(0,100%, 25%)"
要获得浅红色,您只需要增加 L(亮度)分量,因此浅红色将是“颜色:hsl(0,100%, 75%)”。要获得深红色,请减少 L 分量,“颜色:hsl(0,100%, 25%)”
To apply your color, just set the color using
要应用您的颜色,只需使用设置颜色
component.getElement().getStyle().setColor("hsl(0,100%, 25%)")
回答by helios
I don't know in wich format you have the color (I tried to see if GWT uses colors... but they rely heavily on CSS so they don't have specific properties).
我不知道你有哪种格式的颜色(我试图看看 GWT 是否使用颜色......但他们严重依赖 CSS,所以他们没有特定的属性)。
Anyway, if you have one value for each component (Red, green, Blue), and each value ranges between 0 and 255 -this is standard- then apply this algorithm:
无论如何,如果每个组件(红色、绿色、蓝色)都有一个值,并且每个值的范围在 0 到 255 之间——这是标准的——然后应用这个算法:
- for each component
- multiply the original value by a factor (let's say 1.1, 10% more bright)
- convert the float/double value to int
- if this value surpass 255, cut it to 255
- 对于每个组件
- 将原始值乘以一个因子(假设为 1.1,亮度增加 10%)
- 将 float/double 值转换为 int
- 如果该值超过 255,则将其削减至 255
Then you'll have a new color (a new three component tuple).
然后你会有一个新的颜色(一个新的三分量元组)。
Hexa colors
六色
If you have colors in the web format:
如果您有网页格式的颜色:
RRGGBB
RR - two hexa digits for red
GG - two hexa digits for green
BB - two hexa digits for blue
you'll need to convert them to int and back to hexa:
您需要将它们转换为 int 并返回到 hexa:
Hexa string to int
十六进制字符串到 int
Integer.parseInt("AB", 16"); // returns 171
int to Hexa string
int 到十六进制字符串
Integer.toHexaString(171); // returns "AB"
回答by Khushal Vora
Just Add the following function to your code. It will return the hash value for lighter and darker color as per your requirement.
只需将以下函数添加到您的代码中。它将根据您的要求返回浅色和深色的哈希值。
pass two arguments. (1) the hash value of your selected color. (2) how much lighter or darker you want (Ex. if you want 10% lighter shade then pass 0.1 as the second argument and if you want 40% darker then pass -0.4(negative value for darker) as the second argument)
传递两个参数。(1) 您选择的颜色的哈希值。(2) 你想要多少更亮或更暗(例如,如果你想要 10% 更亮的阴影,那么传递 0.1 作为第二个参数,如果你想要 40% 更暗,那么传递 -0.4(更暗的负值)作为第二个参数)
So if you want to find 20% lighter shade of red then call as belowString lightred=convert("ff0000",0.2);
因此,如果您想找到 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;
}

