Golang : Find relative luminance or color brightness
Problem:
You need to find the relative luminance (brightness or perceived brightness) of a color to another color. You also want to check if the luminance of a color is compatible with another color. How to do that?
Solution:
We will use the formula taken from https://www.w3.org/TR/AERT#color-contrast
Color brightness is determined by the following formula:
((Red value X 299) + (Green value X 587) + (Blue value X 114)) / 1000
to calculate the luminance or brightness of a color. You can change the formula for your own need.
Here you go!
package main
import (
"fmt"
"image/color"
"math"
"os"
"strconv"
)
// find out if the two colors are the same
func SameColor(color1, color2 color.RGBA) bool {
red1, green1, blue1, alpha1 := color1.RGBA()
red2, green2, blue2, alpha2 := color2.RGBA()
return red1 == red2 && green1 == green2 && blue1 == blue2 && alpha1 == alpha2
}
// find luminance of a given color - ignoring alpha
func Luminance(aColor color.RGBA) float64 {
// because of
// http://stackoverflow.com/questions/35374300/why-does-golang-rgba-rgba-method-use-and
// we cannot use .RGBA() values. It will screw up the final luminance result
// red, green, blue, _ := aColor.RGBA()
//fmt.Println("red : ", red)
//fmt.Println("green : ", green)
//fmt.Println("blue : ", blue)
// instead, we will use the colors value from 0..255 for calculation purpose
red := aColor.R
green := aColor.G
blue := aColor.B
// need to convert uint32 to float64
return float64(float64(0.299)*float64(red) + float64(0.587)*float64(green) + float64(0.114)*float64(blue))
}
// the diff is big enough?
func Compatible(color1, color2 color.RGBA) bool {
return math.Abs(Luminance(color1)-Luminance(color2)) >= 128.0
}
func SaneColorCheck(arg string) int {
colorCode, err := strconv.Atoi(arg)
if err != nil {
fmt.Println("Input arguments must be integer from 0..255")
os.Exit(-1)
}
if (colorCode > 255) || (colorCode < 0) {
fmt.Println("Invalid color code : ", colorCode)
fmt.Println("Color values must be in range of 0..255")
os.Exit(-1)
}
return colorCode
}
func main() {
if len(os.Args) != 9 {
fmt.Printf("Usage : %s <red1> <green1> <blue1> <alpha1> <red2> <green2> <blue2> <alpha1> \n", os.Args[0])
os.Exit(0)
}
//sanity checks
red1 := uint8(SaneColorCheck(os.Args[1]))
green1 := uint8(SaneColorCheck(os.Args[2]))
blue1 := uint8(SaneColorCheck(os.Args[3]))
alpha1 := uint8(SaneColorCheck(os.Args[4]))
red2 := uint8(SaneColorCheck(os.Args[5]))
green2 := uint8(SaneColorCheck(os.Args[6]))
blue2 := uint8(SaneColorCheck(os.Args[7]))
alpha2 := uint8(SaneColorCheck(os.Args[8]))
fmt.Println("Red 1 : ", red1)
fmt.Println("Green 1 : ", green1)
fmt.Println("Blue 1 : ", blue1)
fmt.Println("Alpha 1 : ", alpha1)
fmt.Println("Red 2 : ", red2)
fmt.Println("Green 2 : ", green2)
fmt.Println("Blue 2 : ", blue2)
fmt.Println("Alpha 2 : ", alpha2)
// create new colors from given arguments/command line parameters
color1 := color.RGBA{red1, green1, blue1, alpha1}
color2 := color.RGBA{red2, green2, blue2, alpha2}
fmt.Println("Color 1 = ", color1)
fmt.Println("Color 2 = ", color2)
fmt.Println("Color 1 same as Color 2 ? : ", SameColor(color1, color2))
fmt.Println("Luminance of color 1 = ", Luminance(color1))
fmt.Println("Luminance of color 2 = ", Luminance(color2))
fmt.Println("Is color 1 and color 2 compatible? : ", Compatible(color1, color2))
}
References:
https://en.wikipedia.org/wiki/Relative_luminance
http://stackoverflow.com/questions/596216/formula-to-determine-brightness-of-rgb-color
https://socketloop.com/tutorials/golang-create-new-color-from-command-line-parameters
By Adam Ng
IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.
Advertisement
Tutorials
+5.3k Golang : Pad file extension automagically
+22.2k Golang : How to run Golang application such as web server in the background or as daemon?
+8.3k Useful methods to access blocked websites
+20.6k Golang : Secure(TLS) connection between server and client
+5.7k Golang : ROT32768 (rotate by 0x80) UTF-8 strings example
+19.9k Golang : Count JSON objects and convert to slice/array
+14k Golang : Fix cannot use buffer (type bytes.Buffer) as type io.Writer(Write method has pointer receiver) error
+14.3k Golang : Get uploaded file name or access uploaded files
+14.2k Golang : syscall.Socket example
+6.1k Golang : Convert Chinese UTF8 characters to Pin Yin
+9.2k nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
+15.6k Golang : ROT47 (Caesar cipher by 47 characters) example