HSLuv, a developer friendly perceptual color space
kuon.ch
kuon.ch
I'm a little sad (disclosure: co-author) that we didn't make oRGB [2] more popular. Perhaps we should put some source code online?
[1] https://www.boronine.com/2012/03/26/Color-Spaces-for-Human-B...
[2] https://www.cs.utah.edu/~bratkova/research/projects/orgb/org...
It is a very naive implementation, more work could be put in optimizing it.
Once I got around to fiddling with it I understood what the paper explained. I'm not new to colorspaces or matrix transformations but it is hard sometimes to grasp the concept from the paper.
btw, the JS port is not perf-optimized (it's a straight compilation from haxe to js).
i hand-ported the C version [1] locally that avoids heap-allocating any objects or arrays, which makes it about 40% faster. i'm hoping it gets to replace the "official" js port at some point, but i still need to run it through all the tests [2]. if anyone is interested in helping out with this (i'm tight on time right now), i'll publish it.
initial benchmark of 100k random RGB triplets completes in 100ms in Chrome 80 and 60ms in Firefox 73, on a pretty average Core i5-7500T @ 2.70GHz. 1M triplets is 680ms in chrome and 421ms in firefox. the official JS port gets 934ms in Chrome and 545ms in Firefox for 1M triplets.
For reference, a typical jpeg image contains < 300k unique colors.
[1] https://github.com/hsluv/hsluv-c
[2] https://github.com/hsluv/hsluv-c/blob/master/tests/scripts/s...
Why do you need a "real" JS version? Is it that you want to be able to read/edit from a human-source, rather than a Haxe-compiled source (which I assume is less legible)?
https://cartocss.readthedocs.io/en/latest/language_elements....
I can really recommend using HSLuv for this kind of thing. I used to use regular RGB values (like #f2cdaa), but it's hard to make features on the map "a bit less blue" without accidentally changing other properties. For example, changing #f2cdaa to #f2cd88 makes it less blue, but also darker.
So a few years ago I switched to using HSL in our stylesheets (and using the HSL tab in the Inkscape colour picker) which makes it easier to reason about the colour changes. But there's still some problems with HSL, as the article describes. For example when choosing road colours, I often want to keep the saturation and lightness the same, but when I make minor roads yellow the change in hue really changes the perceived brightness in HSL.
So HSLuv is great for what I do, since I know that if I get the brightness and saturation of the roads the way I want, I can mess around with the hue without any side effects. Or if I like the colour of the forests but want them slightly less saturated, again no side effects when I make changes.
The big drawback is that there aren't many colour pickers available in HSLuv, mainly just the one on https://www.hsluv.org/ . I haven't found e.g. HSLuv colour picker plugins for Inkscape or the GIMP yet.
I had this code that lets you choose a brighter or darker variant of a color palette, and initially bright yellow looked awfully close to white, so I decided to do this conversion through CIELAB (similar to HSLuv). Some unrelated code was storing these colors in the cloud using hex format, and clients would sync these colors back and forth with the cloud.
Usually, everything worked great. I had no problems, however a couple of users started emailing to complain that their colors had ‘disappeared’! As in - the stored colors had become transparent. I spent at least a few hours auditing syncing code, but found nothing.
A few weeks later I stumbled on the issue by chance: if you select dark green (this specific color configuration only), the color would eventually become transparent.
The thing is - some platforms (e.g. iOS) support wide color, which use RGB values outside the 0 to 1 range. Green would go through the CIELAB brightness conversion, and come out with a negative number for one of the RGB values. This is OK, until you convert it to hex and send it to the cloud for syncing... naive color -> hex conversion will freak out with negative numbers. This got sent to the cloud, and later on, the cloud would send this back to the client, which would use it as a source of truth (and so dark green colors would disappear).
The fix was to write a less naive hex converter. This was a few years back, perhaps by now most color -> hex libraries consider this case.
This is why CIELAB was used, because like the linked HSLuv color space, you can increase brightness across hues with the same perceived brightness shift.
The fact that CIELAB can covert to RGB values outside the usual range is fine, e.g. negative values are fine in wide RGB color space.
A friend of mine designed a color palette for terminals based on the Solarized set, but with some improvements:
which is used for videos such as this: https://www.youtube.com/watch?v=eNt8D1mfwwo
Also, it's crazy how easy it is to recognize homes from SF!
A drone would probably be the best way to shoot the photos for this.
Draw the area you want to capture as a polygon on google maps in DroneDeploy, deploy the drone, off it goes, takes the photos and lands without you needing to do anything. Then just upload the photos, and you get a 3d model processed on their servers an hour or so later.
Any other ideas?
256 is far too many to pick from :) People do their best work when they are under severe constraints. I would recommend a palette that was put together manually without algorithms because someone made sure that colors actually fit well together. My go to source for such project is this site: https://lospec.com/palette-list/
It is discussed at the end of the sinebow article:
It uses ideas similar to the ones described in the article. But the hard part with dark-to-light color gradients is determining what's a pleasing darker or lighter variant of a color. There's a lot of subjectivity involved. You cannot objectively determine a certain color that lies "between" two other colors.
Anyway, I hope my tool helps with quickly creating a nice CSS color gradient.
Converting to CIELUV and mixing there doesn’t seem safe since I don’t think it’s a “convex” color space; you run the risk of ending up with colors that can’t be reproduced properly on a screen.
[1]: https://www.alanzucconi.com/2016/01/06/colour-interpolation/
If you interpolate a bright red and bright cyan (complementary colors), the midpoint would be gray in most color spaces. You can try it in your link. But in polar color spaces (like HSLUV and most of the ones starting with H) if you just lerp each of the numbers you have to pick a direction for the hue, and your cyan—red has to pass through a saturated green, yellow or blue, magenta. That rainbow effect can be nice but doesn’t feel linear. It also creates discontinuities when you change a color stop enough.
Gradients are complicated beasts, and are often rendered wrong, even by popular softwares like browsers.
[1] http://www.iquilezles.org/www/articles/palettes/palettes.htm
[2] https://github.com/thi-ng/color/blob/master/src/gradients.or...
Is there a reason that HSLuv is based on the former (and isn’t “HSLab” instead)?
I don't know why. I just know they do.
If I had to guess, it would be that LUV is designed for additive mixing, and LAB is not, but that is a guess educated by some dimly remembered early highschool physics along with 4th grade art lessons.
Chroma values in LCH differ between Hues, because each Hue has a different potential and max value. That's where HSLuv comes in, where chroma is a percentage value and therefore relative to the Hue, instead of an absolute one. This gives HCL similar usage ergonmics like HSL, thus the name HSLuv.