Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hcl seems to be broken #14

Closed
mbertschler opened this issue Jul 26, 2017 · 3 comments
Closed

Hcl seems to be broken #14

mbertschler opened this issue Jul 26, 2017 · 3 comments

Comments

@mbertschler
Copy link

Hi and thanks for this libary, it looks pretty useful! I generated a gradient over the hues 0 to 360 with the Hcl function, and the output looks wrong. Using the Hsl or Hsv functions causes no problems. Here is my rainbow gradient:

screen shot 2017-07-27 at 00 41 51

The code I used to produce this image using a HTML file that I opened in my browser:

package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"

	"github.com/lucasb-eyer/go-colorful"
)

func main() {
	var out = `<html><head></head><body>`
	for hue := 0; hue < 360; hue++ {
		col := colorful.Hsv(float64(hue), 1, 1)
		r, g, b := col.RGB255()
		out += fmt.Sprintf(`<div style="width:1000px;height:2px;`+
			`background-color:rgb(%d,%d,%d)"></div>`, r, g, b)
	}
	out += "</body></html>"
	err := ioutil.WriteFile(os.ExpandEnv("$HOME/tmp/rgbdebug.html"), []byte(out), 0644)
	if err != nil {
		log.Println(err)
	}
}
@lucasb-eyer
Copy link
Owner

Hi, thanks for the great report with example code and picture, and sorry for the long delay in answering!

This is actually Working As Intended™. The reason is that most of the colors you are trying to compute here don't actually exist. When you're asking to generate a color of hue, say 190° and both chroma and luminosity of 1.0, the corresponding RGB values would be -8.25590, 1.17914, 1.12230, meaning such a color is not representable in the RGB system (and a computer screen).

If you go for less extreme values of luminance and chroma, you will see more and more of the gradient appear. For some values, such as (0.35,0.65), the full gradient exists, and you'll get a nice picture like this:

If you really, really want to have a gradient of higher perceived chroma or luminance, though, there's an ugly workaround that you can do: clamp these non-representable colors to the closes representable one. This will not be entirely correct (converting the gradient to grayscale will show variations in brightness), but depending on your application, it is Good Enough™. I have actually specifically implemented the Clamped function for that purpose, and called it out in the README's "Blending colors" section. I'll add an extra entry to the FAQ, do you have any other suggestion on making it more prominent?

So with that, simply change your code from col.RGB255() to col.Clamped().RGB255() and your demo produces gradients for any values, here is one for (0.8, 0.8), which I also converted to grayscale so you see the non-constant lightness:

@mbertschler
Copy link
Author

@lucasb-eyer thank you for this detailed answer, the behavior makes sense.
I already saw the added FAQ section, maybe you could also add a warning to the comments for the functions where color values outside of the RGB range could be returned? This way you would already see that this could happen before getting frustrated and reading the FAQ.

lucasb-eyer added a commit that referenced this issue Aug 29, 2017
@lucasb-eyer
Copy link
Owner

Good idea, thanks. Done!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants