question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

using `clampChroma` within a conversion sequence results in invalid values

See original GitHub issue

Issue

Using clampChroma within a conversion sequence results in a color object with invalid values.

Expected

Post-clampChroma conversions result in color objects with valid values as defined by culorijs.org/color-spaces.

Example

import {rgb, oklch, clampChroma} from "culori"

const max = {l:1, c:0.322, h:360}

rgb(
  clampChroma(
    oklch({
      l: (max.l * 0.5),
      c: (max.c * 0.5),
      h: (max.h * 0.5),
    })
  )
)

Result

oklch > clampChroma > rgb

r has a negative value, which is outside of the rgb color-space’s documented {min:0, max:1} range.

{mode:'rgb', r:-0.00015269415291914584, g:0.4633768089712706, b:0.40462053745496246}

Other Values

oklch

{mode:'oklch', l:0.5, c:0.161, h:180}

oklch > clampChroma

{mode:'oklch', l:0.5074222643221025, c:0.09214221649333439, h:179.92987163513519}

oklch > rgb

{mode:'rgb', r:-1.1275082865428603, g:0.4943967336505179, b:0.40272542671134454}

Issue Analytics

  • State:open
  • Created 2 years ago
  • Comments:18

github_iconTop GitHub Comments

1reaction
danburzocommented, Jul 25, 2021

I’m currently working through the data you provided. The color table you provided with chromaClamp(oklch()):

Screenshot 2021-07-25 at 21 40 57

This converts the colors to lch, then tries to find the closest chroma that’s displayable while maintaining the lch hue constant, which doesn’t necessarily result in the oklch hue to remain constant. The fact that oklch has its own Chroma and Hue dimensions is incidental — nonetheless it may become confusing.

When doing clampChroma in the color’s original color space, clampChroma(oklch(...), 'oklch') we get rid of the hue drift, and the Lightness increases monotonically:

Screenshot 2021-07-25 at 21 41 08

Now, a remaining problem in both tables is the row corresponding to the OKLCh Lightness = 1. This is due to a quirk/side-effect in OKLab, in that sRGB white has L: 0.9999882345920056, not L: 1. So any OKLCh color with L: 1 will be too bright to be displayable in sRGB on any Chroma (even 0), so clampChroma falls back to clampRgb, and the row appears out of order with the others. I should probably update the OKLab / OKLCh Lightness range on the Color Spaces to be more accurate. (Also, there are other ways to clamp out-of-gamut colors that may be better for this particular situation)

1reaction
Enteleformcommented, Jul 24, 2021

@danburzo Hey I think I might have found some more issues with the chroma clamping.

Video Demonstration:


I wrote a small wrapper for culori that uses unit intervals [0-1] for [r,g,b,h,c,l,a, etc.], but I do have some tests implemented that ensure accurate conversions. I’ll do a bit more debugging tomorrow to double check that the issues aren’t being caused by anything on my end & let you know how it goes.

If I do narrow the issue down to something within culori, I’d be open to setting up a screen sharing session with you if you think it might lead to any insights or want to check out any of the generated data.


This is the function I’m calling in the demo:

Color.Range({
  count,
  color:  {h:(hue/100), c:(chroma/100), l:0},
  result: "Hex6",
  modify: {
    l: {ease:"Linear", range:{from:(min/100), to:(max/100)}},
  },
})

The count, min, max, hue, & chroma variables are being passed to a Svelte component via Storybook’s controls.

h and c remain static for each generated range, and l values are being generated from min to max via the easing library, after which all of the resulting color objects are passed through my wrapper which converts the unit interval values to culori values and then runs them through a similar color conversion process as initially detailed in this issue, finally applying the generated hex values to the HTML elements.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Issues · Evercoder/culori - GitHub
Add support for WCAG3 contrast using APCA. #177 opened 13 hours ago by meodai ... using clampChroma within a conversion sequence results in...
Read more >
Summarize tool and invalid values - Alteryx Community
I want to use the "Sum" function in summarize, however, I keep getting "conversion errors." I believe the data type and commas within...
Read more >
I got an error while running the sequence - UiPath Forum
Invalid L-value expression.:Reference expressions cannot end with Conversion. The provided expression's type must exactly match the type T ...
Read more >
Appendix A: 3rd Party Licenses - Boris FX
BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS...
Read more >
glibmm 2.4 invalid byte sequence in conversion input
An initialization of the locale is needed E.g. std::locale::global(std::locale("")); in order to use ustring and have it do the stream ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found