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.
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:
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.
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_HSV and http://www.acasystems.com/en/color-picker/faq-hsb-hsv-color.htm
Edit: According to the comments, the java.awt.Color
class can't be used in GWT. Since the only part of theColor
class 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:
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.
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!)
This Wikipedia article on HSL and HSV color models explains far more than you probably want to know :)
Have a look at this HSB demo.
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
.
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.
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):
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 dAmount
is truly in the range 0..1.
The Java Color documentation looks like the Color
class has all sorts of useful methods. (Edit: I just noticed you said you're using gwt
not 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!
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).
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:
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:
Hexa string to int
Integer.parseInt("AB", 16"); // returns 171
int to Hexa string
Integer.toHexaString(171); // returns "AB"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With