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

Color "cap" unexpected output #27

Open
jmw86069 opened this issue Jul 9, 2021 · 1 comment
Open

Color "cap" unexpected output #27

jmw86069 opened this issue Jul 9, 2021 · 1 comment

Comments

@jmw86069
Copy link

jmw86069 commented Jul 9, 2021

I really love this package - and pretty much all your packages!

I'm reporting a bug I discovered with some HCL input values. Current workaround is not to request these HCL values, but no indication when it occurs. :) It could be a memory leak issue.

As I understand it, when farver converts a color type to RGB or hex, each RGB channel is "capped" at 255.

I observed three behaviors:

  1. When an RGB channel value exceeds 255, it is set to 255, sometimes causing the color hue to shift.
  2. Some colors do weird things, for example blue converted to red.
  3. The vast huge majority of colors are converted without issue. Respect the farver.

Edit: I can't tell if the "cap" step is the cause of red.

blue_gradient_bug <- farver::encode_colour(
   cbind(h=250,
   c=c(140, 130, 129, 128, 127, 120, 100, 80, 60),
   l=20), from="hcl");
colorspace::swatchplot(blue_gradient_bug)

I'll narrate briefly:

  • It requests colors using HCL, with h=250 (blue), luminance l=20 (dark).
  • It requests a range of chroma c values from 140 to 60.
  • chroma 140 and 130 return red
  • chroma 129 returns cyan
  • chroma 128 and lower returns blue.

The hcl output is shown below:

farver::decode_colour(blue_gradient_bug, to="hcl")

Produces this table of HCL values:

h c l
12.2 179.0 53.2
12.2 179.0 53.2
196.9 71.3 89.1
246.1 98.3 64.2
254.5 114.6 55.8
262.4 132.5 42.7
263.2 113.4 34.5
261.3 79.1 27.3
258.4 56.9 23.2

The cyan output is expected - RGB blue channel value above 255, capped at 255. The green channel must be high, producing cyan.

The red output is unexpected.

I should post the RGB output:

farver::convert_colour(cbind(h=250,
   c=c(140, 130, 129, 128, 127, 120, 100, 80, 60),
   l=20), from="hcl", to="rgb")
r g b
255 0.0 0
255 0.0 0
0 247.7 255
0 161.9 255
0 132.1 255
0 80.4 255
0 59.0 219
0 53.7 161
0 51.3 125

I tried to circumvent the issue by direct conversion of HCL to something else (e.g. "hcl" to "hsl") - but I think everything goes through an RGB intermediate? Could be wrong there, the code is clever with the dynamic function calls.

Potential workarounds:

  • Fix the source of red - possible memory bug if numeric values are showing up in odd places. Total guess. I noticed in the upstream ColorSpace, it appears to subtract 255 only once if a channel exceeds 255 - what happens if blue channel is 600? Not sure why that would return R=255,B=0,G=0.
  • Rgb::Cap() scales all RGB values so the max value is 255, instead of capping at 255; preserving the hue. This would reduce brightness for some colors.
  • Something to indicate when color conversion went badly, so I can tell what is out of bounds.

Sorry I couldn't yet determine where the bug is occurring, maybe it will make sense to you?

@jmw86069
Copy link
Author

I know this issue is low-priority and that's alright. :)
I'm working around by forcing in-gamut colors for each hue in my work.

I'm just posting a screenshot, realizing I could have just copied/pasted. smh

These colors were all obtained with hue=250 and should more or less be blue:
image

The first 2 colors have chroma set out of gamut for blue, and they are corrected weirdly.

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

1 participant