You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
1.9 KiB
82 lines
1.9 KiB
package huecolor
|
|
|
|
import (
|
|
"math"
|
|
)
|
|
|
|
// ConvertXY converts the RGB value to XY and brightness and snaps it to the color gamut.
|
|
func ConvertXY(r, g, b float64) (x, y float64) {
|
|
x, y, z := convertXYZ(correctGamma(r, g, b))
|
|
|
|
return x / (x + y + z), y / (x + y + z)
|
|
}
|
|
|
|
// ConvertRGB converts back the values for ConvertXY to RGB. This does not gurantee that
|
|
// `ConvertRGB(ConvertXY(r, g, b))` returns the same `r`, `g` and `b` because of Gamut
|
|
// clamping.
|
|
func ConvertRGB(x, y, bri float64) (r, g, b float64) {
|
|
z := (1 - x - y)
|
|
y2 := bri
|
|
x2 := (y2 / y) * x
|
|
z2 := (y2 / y) * z
|
|
|
|
r = x2*1.4628067 - y2*0.1840623 - z2*0.2743606
|
|
g = -x2*0.5217933 + y2*1.4472381 + z2*0.0677227
|
|
b = x2*0.0349342 - y2*0.0968930 + z2*1.2884099
|
|
|
|
return reverseGamma(r, g, b)
|
|
}
|
|
|
|
// convertXYZ converts the RGB values to XYZ using the Wide RGB D65 conversion formula.
|
|
func convertXYZ(r, g, b float64) (x, y, z float64) {
|
|
return r*0.649926 + g*0.103455 + b*0.197109,
|
|
r*0.234327 + g*0.743075 + b*0.022598,
|
|
r*0.0000000 + g*0.053077 + b*1.035763
|
|
}
|
|
|
|
// correctGamma applies a gamma correction to the RGB values, which makes the color
|
|
// more vivid and more the like the color displayed on the screen of your device.
|
|
func correctGamma(r, g, b float64) (r2, g2, b2 float64) {
|
|
if r > 0.04045 {
|
|
r2 = math.Pow((r+0.055)/1.055, 2.4)
|
|
} else {
|
|
r2 = r / 12.92
|
|
}
|
|
|
|
if g > 0.04045 {
|
|
g2 = math.Pow((g+0.055)/1.055, 2.4)
|
|
} else {
|
|
g2 = g / 12.92
|
|
}
|
|
|
|
if b > 0.04045 {
|
|
b2 = math.Pow((b+0.055)/1.055, 2.4)
|
|
} else {
|
|
b2 = b / 12.92
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// reverseGamma applies a reverse gamma correction to the RGB values to make them
|
|
func reverseGamma(r, g, b float64) (r2, g2, b2 float64) {
|
|
if r >= 0.0031308 {
|
|
r2 = 1.055*math.Pow(r, 1/2.4) - 0.055
|
|
} else {
|
|
r2 = r * 12.92
|
|
}
|
|
|
|
if g >= 0.0031308 {
|
|
g2 = 1.055*math.Pow(g, 1/2.4) - 0.055
|
|
} else {
|
|
g2 = g * 12.92
|
|
}
|
|
|
|
if b >= 0.0031308 {
|
|
b2 = 1.055*math.Pow(b, 1/2.4) - 0.055
|
|
} else {
|
|
b2 = b * 12.92
|
|
}
|
|
|
|
return
|
|
}
|