Archive for November, 2006

Calculating Color Brightness

I was working on a website today, and I stumbled into a problem of needing to compute the brightness of a color, so that if it is a background color, I know whether to show white text or black text. My first thought was to simply add up the RGB components of the color and use that value. It turns out that is completely wrong, since pure green looks much brighter than pure blue:

Green

Green
Blue

Blue

Obviously, you’d want to have white text against the blue background, but black text against the green background.

Now given, there is no way any sane person would use those specific colors as background colors. But the problem still applies to many other, more muted (read: useful), colors. So how do you find the apparent brightness of a color? It turns out to be much more difficult than I thought.

I knew that in Photoshop you can convert your picture from the RGB color space to the Lab color space. Lab colors are described by two color components a and b, and a Lightness component. A good way to convert your photo to black and white is to convert it to Lab, and then get rid of the a and b channels, leaving just the Lightness channel.

So I needed some way to convert from RGB to Lab. Must be easy, right? No. it turns out that there is no absolute conversion between RGB and Lab, because of the nature of the design of the colorspaces. But you can do it if you use the intermediate CIE 1931 (also known as XYZ) color space, if you pick a reference white point to do the conversion. This means that you can get different XYZ colors for the same RGB color depending on what you decide “white” is.

Here is a color conversion calculator. Enter your colors in any color space, pick a reference point, and it will give you the color in many color spaces.

They also give the algorithms used to do the conversion on their site. Below is the algorithm to convert from RGB to XYZ:

var_R = ( R / 255 )        // scales var_R to between 0 and 1
var_G = ( G / 255 )
var_B = ( B / 255 )
 
if ( var_R > 0.04045 ) var_R = ( ( var_R + 0.055 ) / 1.055 ) ^ 2.4
else                   var_R = var_R / 12.92
if ( var_G > 0.04045 ) var_G = ( ( var_G + 0.055 ) / 1.055 ) ^ 2.4
else                   var_G = var_G / 12.92
if ( var_B > 0.04045 ) var_B = ( ( var_B + 0.055 ) / 1.055 ) ^ 2.4
else                   var_B = var_B / 12.92
 
var_R = var_R × 100
var_G = var_G × 100
var_B = var_B × 100
 
//Observer. = 2°, Illuminant = D65
X = var_R × 0.4124 + var_G × 0.3576 + var_B × 0.1805
Y = var_R × 0.2126 + var_G × 0.7152 + var_B × 0.0722
Z = var_R × 0.0193 + var_G × 0.1192 + var_B × 0.9505

The conversion from XYZ to Lab is more straightforward and doesn’t require vector math.

var_X = X / ref_X          //ref_X =  95.047  Observer= 2°, Illuminant= D65
var_Y = Y / ref_Y          //ref_Y = 100.000
var_Z = Z / ref_Z          //ref_Z = 108.883
 
if ( var_X > 0.008856 ) var_X = var_X ^ ( 1/3 )
else                    var_X = ( 7.787 × var_X ) + ( 16 / 116 )
if ( var_Y > 0.008856 ) var_Y = var_Y ^ ( 1/3 )
else                    var_Y = ( 7.787 × var_Y ) + ( 16 / 116 )
if ( var_Z > 0.008856 ) var_Z = var_Z ^ ( 1/3 )
else                    var_Z = ( 7.787 × var_Z ) + ( 16 / 116 )
 
L = ( 116 × var_Y ) - 16
a = 500 × ( var_X - var_Y )
b = 200 × ( var_Y - var_Z )

Here are some sites I looked at while trying to figure out exactly what was going on in those functions.
Color Conversion Algorithms
Useful Color Equations

I wrote these two functions in PHP, and after running the output of one on the other, I was able to get the brightness value for the colors.

Here is the result of my programming. A web palette of 216 colors in a table, with their brightness values in each cell. The numbers are colored light if the background is dark, and dark if the background is light.

No Comments

Create a weird colored star thing in Photoshop

This tutorial will show you how to create the most beautiful image you have ever seen. I’m serious. There is nothing you could ever like more than this.

Ok, now that you’ve seen it, there is nothing you would rather do more than make this image. This is not a question.

Step 1:
Create a blank 20×15 pixel image. That’s right. PIXELS. It’s going to be small. Then go to Filter -> Noise -> Add Noise. Add some colored noise. Here is a zoomed-in version of what it should look like:

Step 2:
Go to Image -> Image Size, and resize this image to something more useful, like say, 1200 pixels wide. It should look like this:

Step 3:
It looks pretty dumb. Go to Filter -> Pixelate -> Crystallize, and choose a cell size of about 50 pixels. Experiment with it.

It looks a little better now.

Step 4:
Now we need some empty space around the colors. Double-click the “Background” layer to turn it into a regular layer. Then either enlarge the canvas to add space around the image, or shrink the layer. Your choice. It should look like this now.

Step 5:
Now go to Filter -> Blur -> Radial Blur. Change the blur method to “zoom,” change the amount to 100, and change the quality to best. After it does its thing, do it again. (Press CTRL+F to repeat the last filter.)

Step 6:
Now comes the tricky part. We’re going to do Glowing Edges to this. Go to Filter -> Stylize -> Glowing Edges. Play with the width and brightness a bit to see what happens. I ended up only increasing the brightness slightly. After you do that, you’ll end up with this.

Step 7:
If you invert the layer, then all the black turns to white, and since the colors were just random anyway, they don’t look a whole lot different.

Now you can use this in other images, and it’s even got transparency so it will blend nicely, or you can add a solid white background to finish it off.

You can tweak the colors to match whatever project you’re working on by playing with the curves for red, green and blue. You can completely remove the green for example, if green would clash with the rest of your image.

No Comments