An algorithm for selecting a dark color similar to a light color

I'm making a chat where users can select their own preferred text color. The same chat will be displayed in several places in the website. In some places the background will be dark, and in others - light. As a result, most selected colors will probably be illegible in some of the chatboxes.

So I'm looking for an algorithm that, given a color which works well on one type of background (light or dark), produces another color which looks good on the opposite type of background and is as similar to the first color as possible (so the user gets the impression that he is using the same color everywhere).

I know this is probably impossible to do perfectly, but any attempts are welcome.


Look into http://en.wikipedia.org/wiki/HSL_and_HSV

As long as you keep the hue and saturation constant it would seem the same color, and you can play with the brightness for contrast with the background


To make a darker color multiply the RGB components by 0.5 or 0.75 for example.

Scaling the RGB values, each by the same factor, has the effect of making a color darker or brighter without changing the hue.


Okay, after reading about a couple of things here and there. Here is what I was able to find out so far.

First of all I would like to highlight a few points and make sure that anyone that is reading my answer is able to understand what I'm talking about here.

What is a Color Space?

A range of colors can be created by the primary colors of pigment and these colors then define a specific color space. Color space, also known as the color model (or color system), is an abstract mathematical model which simply describes the range of colors as tuples of numbers, typically as 3 or 4 values or color components (ex: RGB). Basically speaking, color space is an elaboration of the coordinate system and sub-space. Each color in the system is represented by a single dot.


Most of us developers uses one of the following color spaces ( HEX , RGB , RGBA ) some even go to use ( CMYK , HSV & HSL , etc ) Which can provide you with any color that you want through the combination of the main colors ( Red , Green , Blue , Alpha ).

If we want to know if a color is close to another color we look at it with our eyes, but since we would like to have the computer programmatically do it for us then we have look at it in a mathematical manner.

Given that color A is Red in HEX color space #FF0000 and color B is Green in HEX color space as well #00FF00 and from our understanding of RGB we the have the first two values are the representation of the Red color, the second two values are the representation of the Green color and the last two values are the representation of the Blue color and since we know that each one these values are a number representation of its value (0-9) then (A, B, C, D, F) = (10, 11, 12, 13, 14). Then we can draw the color in a 3D dimension and calculate the distance between them using a law like Euclidean.

EX: A = (R1 = FF, G1 = 00, B1 = 00)
B = (R2 = 00, G2 = FF, B2 = 00)
We have our two point here, now we can use Euclidean law
Distance = sqrt((R2 - R1)^2 + (G2 - G1)^2 + (B2 - B1)^2)

So far so good, right?
Nope .

Wither we used HEX, RGBA, CMYK or any other color space we won't be able to know anything except the distance between the two colors in their color space which sometime might be completely different color yet the distance is between them is low because they don't take in consideration how our eyes see colors.

But there exist other color spaces ( scientific ones) that take in consideration the way our eyes see colors and how our mind interpret them. One of these are Lab .


Color Transformation

A color in one absolute color space can be converted into another absolute color space, and back again, in general; however, some color spaces may have gamut limitations, and converting colors that lie outside that gamut will not produce correct results. There are also likely to be rounding errors, especially if the popular range of only 256 distinct values per component (8-bit color) is used.


What is gamut?

In color reproduction, including computer graphics and photography, the gamut, or color gamut, is a certain complete subset of colors. The most common usage refers to the subset of colors which can be accurately represented in a given circumstance, such as within a given color space or by a certain output device.


Now that we understood the basic functionalities that we are going to implement let's start coding knowing the following equation.

HEX To RGB

We have HEX as the color representation in hexadecimal value we just have to get their decimal values and that it, now we have our color in RGB color space.
A = RGB(255, 0, 0) Red
B = RGB(0, 255, 0) Green

RGB To XYZ

We have to follow the following mathematical law
color = current color / 255
if color > 0.04045
color = ( ( color + 0.055 ) / 1.055 ) ^ 2.4
else
color = color / 12.92
color = color * 100
X = colorRed * 0.4124 + colorGreen * 0.3576 + colorBlue * 0.1805
Y = colorRed * 0.2126 + colorGreen * 0.7152 + colorBlue * 0.0722
Z = colorRed * 0.0193 + colorGreen * 0.1192 + colorBlue * 0.9505
That' it

EX:- A = RGB(255, 0, 0) Red
colorRed = 255/255
colorGreen = 0/255
colorBlue = 0/255

if (colorRed > 0.04045){
    colorRed = ( ( colorRed + 0.055 ) / 1.055 ) ^ 2.4
}else{
    colorRed = colorRed / 12.92
}
if (colorGreen > 0.04045){
    colorGreen = ( ( colorGreen + 0.055 ) / 1.055 ) ^ 2.4
}else{<br/>
    colorGreen = colorGreen / 12.92
}
if (colorBlue > 0.04045){
    colorBlue = ( ( colorBlue + 0.055 ) / 1.055 ) ^ 2.4
}else{
    colorBlue = colorBlue / 12.92
}

colorRed = colorRed * 100
colorGreen = colorGreen * 100
colorBlue = colorBlue * 100

X = (colorRed * 0.4124) + (colorGreen * 0.3576) + (colorBlue * 0.1805)
Y = (colorRed * 0.2126) + (colorGreen * 0.7152) + (colorBlue * 0.0722)
Z = (colorRed * 0.0193) + (colorGreen * 0.1192) + (colorBlue * 0.9505)

A XYZ(X, Y, Z)

XYZ To Lab

// Reference-X, Reference-Y and Reference-Z refer to specific illuminants and observers.

X = X / Reference-X
Y = Y / Reference-Y
Z = Z / Reference-Z

if ( X > 0.008856 ) {
    X = X ^ ( 1/3 )
}else{
    X = ( 7.787 * X ) + ( 16 / 116 )
}
if ( Y > 0.008856 ) {
    Y = Y ^ ( 1/3 )
}else{
    Y = ( 7.787 * Y ) + ( 16 / 116 )
}
if ( Z > 0.008856 ) {
    Z = Z ^ ( 1/3 )
}else{
    Z = ( 7.787 * Z ) + ( 16 / 116 )
}

CIE-L* = ( 116 * Y ) - 16
CIE-a* = 500 * ( X - Y )
CIE-b* = 200 * ( Y - Z )


References

//2o Observer (CIE 1931)
// X2, Y2, Z2
CIE2_A = {109.850f, 100f, 35.585f} //Incandescent
CIE2_C = {98.074f, 100f, 118.232f}
CIE2_D50 = {96.422f, 100f, 82.521f}
CIE2_D55 = {95.682f, 100f, 92.149f}
CIE2_D65 = {95.047f, 100f, 108.883f} //Daylight
CIE2_D75 = {94.972f, 100f, 122.638f}
CIE2_F2 = {99.187f, 100f, 67.395f} //Fluorescent
CIE2_F7 = {95.044f, 100f, 108.755f}
CIE2_F11 = {100.966f, 100f, 64.370f}

//10o Observer (CIE 1964)
// X2, Y2, Z2
CIE10_A = {111.144f, 100f, 35.200f} //Incandescent
CIE10_C = {97.285f, 100f, 116.145f}
CIE10_D50 = {96.720f, 100f, 81.427f}
CIE10_D55 = {95.799f, 100f, 90.926f}
CIE10_D65 = {94.811f, 100f, 107.304f} //Daylight
CIE10_D75 = {94.416f, 100f, 120.641f}
CIE10_F2 = {103.280f, 100f, 69.026f} //Fluorescent
CIE10_F7 = {95.792f, 100f, 107.687f}
CIE10_F11 = {103.866f, 100f, 65.627f}


Distance between two colors in Lap color Space

Treat the color as 3d dimension like we did earlier and now we have the exact distance between the two colors with respect to the human eye.


To Include

Research more for a technique that we should use in order to change the color yet have the same color but feels like another one for the human eyes and through it we can see the background and the things that are drawn on top of it using the same color.

链接地址: http://www.djcxy.com/p/15268.html

上一篇: 六角形透明度的颜色

下一篇: 用于选择类似于浅色的深色的算法