A color management and conversion library that focuses on maintaining correctness, flexibility and ease of...

A color management and conversion library that focuses on maintaining correctness, flexibility and ease of use

palette

. It makes use of the type system to prevent mistakes, support a wide range of color spaces including user defined variants and offer different ways of integrating with other libraries.

Usage and examples can be found in the palette directory.

Online Documentation

Released

Master branch

Minimum Supported Rust Version (MSRV)

This version of Palette has been automatically tested with Rust version 1.51.0 and the stable, beta, and nightly channels. Future versions of the library may advance the minimum supported version to make use of new language features, but this will be considered a breaking change.

Contributing

All sorts of contributions are welcome (including especially speling corrections), so take a look at CONTRIBUTING.md for guidelines, if you are interested.

License

Licensed under either of

  • Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
  • MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)

at your option.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Issues

Collection of the latest Issues

NeverGivinUp

NeverGivinUp

12

When adding any use statement from my local palette crate to my library -- I have not tried using the official version -- I get the following error:

The error goes away, when I comment out the line impl_scalar_binop!(Div::div, DivAssign::div_assign, [f32, f64]);

I believe is unrelated to my local changes and it certainly is unrelated to the code, where the error occurs. It may be related to a bug in the rust compiler.

Ogeon

Ogeon

0

Description

Change all color types to have the component type parameter first and the meta type parameter (standard or white point) second. For example Rgb<Srgb, f32> would become Rgb<f32, Srgb>. The same goes if the type has multiple component types, like a separate alpha type. They would all be moved to the beginning.

See the motivation below for my hypothesis, but it would be interesting to know if other people have the same impression. Have you found yourself specifying more type parameters than should be necessary? Or adding a type alias to skip it? Or the opposite situation, that it's better as it is?

Motivation

This may seem insignificant, and that's what I pretty much thought until more recently, but it would likely make the types more ergonomic when using the default meta types. My experience so far shows that the component type varies the most, while the standard or white point is more likely to never change at all. The problem with the current order is that one has to specify the meta type to get to the component type in the list. For example let color: Hsv<_, f32> = ... or let color: Hsv<Srgb, f32> = ..., while the proposed order would allow let color: Hsv<f32> = .... This pops up now and again when there isn't a type alias that specifies the first parameter.

Ogeon

Ogeon

0

Description

Add the remaining blend modes from https://www.w3.org/TR/compositing-1: hue, saturation, color, luminosity. Also try to implement them for polar color spaces, as suggested in #178, to be able to close it. They should be implemented as their own trait, since they are quite different form other blend modes. The color types must have some counterpart to the auxiliary functions that they consist of.

Motivation

These blend modes are also useful and should not be left out. The trait rework in #273 makes it easier to implement them than before, so it's time for another attempt. It would complete the set of blend modes.

Ogeon

Ogeon

documentation
0

The error message suggests that Srgba<u8> would need to implement WithAlpha<f32>, due to this:

`

Ideas for making it more clear:

  • Change the impl above to dodge the error message. It may need to be a bit more strict.
  • Document the exceptions in the conversion implementation. Basically that component types, white points and standards don't change when converting between color spaces.
  • See if there's an attribute that can be added to improve the message when a conversion impl is missing.

See discussion https://github.com/Ogeon/palette/discussions/267 where it was brought up.

Ogeon

Ogeon

4

Description

Björn Ottosson has published more perceptually even alternatives to HSV and HSL, as described in https://bottosson.github.io/posts/colorpicker/. The conversion from other color spaces would be based on the already supported Oklab.

Motivation

Given the shortcomings of HSL, HSV and HWB, it would be nice to be able to offer some more alternatives. Not only for color pickers but also for applications like generative art, where HSLuv is already used for the same reasons, or other situations where a human isn't picking the colors.

Ogeon

Ogeon

0

Description

The traits in chromatic_adaptation have turned out to "do too much". They both adapt white spaces and convert between color spaces. I'm thinking they could be changed to apply to Xyz only, since that's the space where it's done, and leave any conversion to the user. That way we don't force any kind of clamping and don't do anything else that may be surprising or unnecessarily destructive.

For extra flexibility, though, we could add a function that takes any source and destination white space, with Xyz<Any, T> parameters. A light source, for example, may not necessarily match a static white point.

Motivation

I want to remove hidden side effects and make them Do One Thing. Plus detailed control.

arzg

arzg

3

It seems that the state-of-the-art currently in colour spaces is the CAM16 colour space. @nschloe wrote a paper concerning improvements to the colour space, which they then implemented in Python as part of a larger colour space library. I know very little about colour spaces or mathematics, so I don’t know how much I could do apart from mechanically porting the Python implementation to Rust. Is this something that would be helpful?

Ogeon

Ogeon

0

This is mostly relevant for conversion methods that are larger than a handful of lines. It should be possible to help the compiler de-duplicate a lot of code where the same methods are used with different type parameters. Parameters such as white point or RGB standard don't affect the code more than changing a few constants, so they should be possible to "outline" as a function that is only generic over the component type:

This avoids generating nearly identical copies for each white point that is used. The exact way of passing the data around is up to what works best for the situation.

piegamesde

piegamesde

7

Color blending in the Lch color space would be awesome to have.

Some resources and implementations I found on the way:

  • https://web.archive.org/web/20150214062932/http://www.stuartdenman.com/improved-color-blending
  • http://labs.adamluptak.com/javascript-color-blending/
  • https://ninedegreesbelow.com/photography/gimp-lch-blend-modes.html
  • #404

I didn't find much sample code, but most implementations seem to do simple linear interpolation with special wrap-around handling of the hue channel.

okaneco

okaneco

4

Have you investigated anything with CIECAM02? I'm interested in this space because of a website I use which has listings of watercolor pigment colorimetry measurements in CIECAM Jab and it'd be cool to have. I know there are some differences between Jab and Jch and that it's a complicated model.

I'd be interested in helping implement this but didn't want to be a hassle if I got in the way since I've not contributed something of this scale here.

okaneco

okaneco

7

This came up while working on #166

These are the current keywords in the cargo manifest:

Goal

Improve search of palette on crates.io

Issue

According to the documentation you can have up to 5 keywords. That said, crate discovery isn't great on the site with how it handles searching and separating exact matches, keywords, and categories. I've not had pleasant experiences trying to find things on there in the past or at least some type of "canonical" crate for a task.

Searching "palette" in the keywords, it doesn't come up but palette_derive does so that might be a good keyword to add: https://crates.io/keywords/palette. Others like like https://crates.io/keywords/space don't initially seem to be a good use of keyword because of how "dumb" the search is, however "colo[u]r space" brings up the crate as a top hit so keywords combine in your favor. I think it pulls some from the readme since searching for "srgb", palette and *_derive came up 2nd and 3rd, along with other crates being surfaced in similar color space/model searches.

Suggestions

Add at least one more keyword. I think "pixel" may be the best candidate over "palette", since the crate doesn't show up while searching it https://crates.io/search?q=pixel and that's very relevant to what a lot of us want to do. Ideally search wouldn't differentiate color/colour so "colour" is probably still worth a keyword instead of replacing it with "palette".

It might make more sense to include a sentence of all the color models that palette works with and a sentence of some features people might be looking for in the description so it'll get hits in the search. An example being if you search "hwb", palette doesn't appear in the results. palette generally does well showing up at the top for queries like "srgb". Whatever you think the most important features are that can fit in 2-3 sentences probably makes the most sense. In this research, I looked up "lab" and palette doesn't surface however two CIEDE2000 color difference crates do that I didn't know about (funny enough, they avoid the test case that gave us errors until we switched to f64).

These are some of the words that I think should be in the description based on lack of presence in searches:

  • Alpha composition/alpha compositing
  • Luma, luminance
  • color difference, contrast ratio
  • HSL, HSV, HWB, Lab, Lch (HCL), RGB, Xyz, Yxy

Motivation

I'm by no means an expert but this is inspired by not finding this crate until after seeing an announcement for version 0.5 came out and I'd already painfully reimplemented parts of this in my projects. Search never surfaced the crate despite doing things I was really interested in like the color handling and gradients. It can save a lot of headaches having a crate that does color so well and plays nicely with image which is probably going to be most new rust users' experience with manipulating pixels.

Ogeon

Ogeon

2

It should have about the same API as today, where it still makes sense, but overall modernized. Also fulfill this:

  • make it #[no_std] enabled
  • support more than just linear interpolation
  • the Take iterator should be inclusive, meaning both ends are part of the output for n > 1
  • support slicing with at least x..=y, but other ranges may also make sense

The first two points may go hand in hand, by replacing the internal Vec with some input collection.

grtlr

grtlr

3

A lot of color schemes that are used in data visualization (https://github.com/d3/d3-scale-chromatic/) are based on b-spline interpolations. Palette already has linear interpolation (Mix), is adding b-spline interpolation something that you would consider?

I have done first experiments with the bspline crate (which is only passively maintained) and it works well for LinSrgb. Here is an example of the Spectral diverging color scheme:

Thanks!

0x7CFE

0x7CFE

documentation
1

Current crate documentation does not provide a section that covers color space conversion. I may suggest adding "color conversion" chapter somewhere near top-level documentation index.

Such a section should probably include brief description of different color spaces and typical scenarios, like conversion from HSV to sRGB and vice versa.

mitchmindtree

mitchmindtree

documentation
7

Hi @Ogeon! I'm (finally) updating nannou from 0.2 to 0.4 and I'm a little confused about the distinction between the Srgb and Linear<Srgb> encodings.

I'd always thought that sRGB and Linear were two distinct encodings. Specifically, I thought that Linear was a direct mapping to the hardware output, whereas sRGB was a mapping that is friendlier to the perceivable colour range. What does it mean to have Linear<Srgb>?

Sorry for the ordinary question! Feel free to point me elsewhere if there's somewhere I can read up properly on this :pray:

Frizi

Frizi

defect
1

There is a long-standing serde bug without an intention to fix, that causes all structs that use #[serde(flatten)] attribute to be interpreted as maps during serialization. Unfortunately, that means that all formats that differentiate between structs and maps cannot properly round-trip palette types through serde. It works on JSON, because it has no distinction between structs and maps.

An example format to test against would be RON (and here is it's related issue). For binary format that suffers from the same issue, check bincode.

In order to fix this, palette needs to implement serialization manually, and use serialize_struct with all the expected fields being serialized directly. That way serde will always treat those types as structs uniformly. This is not fully trivial due to generics, but should be possible with additional crate-private traits that operate on struct serializers adding all necessary fields.

Example RON behaviour of serializing Srgba with current setup:

Deserialization of above fails, because generated deserializer expects identifiers in place of map keys, but ron always passes strings. In order to deserialze above struct properly, the representation must be manually changed to

With manual serialization implementation, the ideal supported serialized form would be one of those, or ideally both:

For reference, this is how amethyst implements transform deserialization as seq and as map to accept both formats as valid in a vector field.

HeroicKatora

HeroicKatora

5

Requested features

It would be awesome to have support for the ITU-R Recommendations family of color representations. The primary ones of concern for today are BT.709, BT.2020 and BT.2100 for HD, 4k and high-dynamic range respectively.

Motivation

These are in use by video codes and other media alike, most prominently mpeg using the YCbCr encoding of BT.709. This would lay the ground work for implementing correct consumers and producers of these raw video codecs in rust. Additionally, it would improve the state of interoperability with external libraries such as ffmpeg without sacrificing performance (such as copying/converting image data with another ffi).

Implementation notes

All standards use the same whitepoint and sRGB and BT.709 even use the same primaries. The difference is a slightly changed transfer function and a quantization function for digital output data (8-bit or 10-bit). A different primary configuration is employed by the other two standards as well as a slightly more involved definition of the transfer function but still similar in effect. The same holds for the quantization.

Open questions

There standards are defined for various different bit depths. It is an open question on how this is best mapped to the api. Staying in floating point representation is not enough, as the quantization is not defined as a simple scaling.

References

https://en.wikipedia.org/wiki/Rec._709 http://www.itu.int/rec/R-REC-BT.709-6-201506-I/en https://en.wikipedia.org/wiki/Rec._2020 https://en.wikipedia.org/wiki/Rec._2100

Checklist

  • analog YUV color representation
  • accurate standardized, depth dependent YCbCr quantization and encoding
  • BT.601
    • both RGB standards
    • YUV difference conversion
    • quantization function
  • BT.709
    • RGB standard
    • YUV difference conversion
    • quantization function
  • BT.2020
  • BT.2100
    • HLG
    • PQ–deferred, see #198
tatref

tatref

2

Hi!

Would it be interesting to add support for spectrum to XYZ conversions?

The spectrum can be represented as a [f32; XXX] (XXX depending on the sampling of the spectrum). Where the f32 values are the intensities (in arbitrary units), for each wavelength from ~400 to ~800 nm. Then the XYZ coordinates are a matter of simple matrix multiplication, given the XYZ weights.

The weights are available on different websites (http://www.cvrl.org/cie.htm) There is also analytic aproximations (http://jcgt.org/published/0002/02/01/paper.pdf)

I've already started a POC, so I might submit a pull request (the code is not that clean yet though).

Tell me what you think about this.

Ogeon

Ogeon

wish list
3

Add some sort of support for ICC profiles. Could be statically embedded, fully dynamic or both. This will make things like accurate CMYK possible, as discussed in #6.

Ogeon

Ogeon

wish list
0

The Munsell color system may be an interesting addition from a more artistic point of view. RIT provides some data files that may be used to convert from Munsell to xyY, but I haven't found any clear terms of use for those, but the colors themselves are not copyrighted and it looks like it's under a section of free-to-use stuff. That will need more investigation, since we must consider possible commercial use of this library.

Embedding a Munsell database into the library may be quite a bit of bloat, so this should probably be included as an opt-in feature.

flosse

flosse

wish list
4

It would be cool to be able to convert to an from CMYK :)

Information - Updated Jun 21, 2022

Stars: 449
Forks: 45
Issues: 24

Repositories & Extras

CDRS is looking for maintainers

CDRS is Apache Cassandra driver written in pure Rust

CDRS is looking for maintainers
Http

371

A push parser for the HTTP 1

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2

A push parser for the HTTP 1

The arkworks ecosystem consist of Rust libraries for designing and working with zero knowledge succinct...

This library is released under the MIT License and the Apache v2 License (see License)

The arkworks ecosystem consist of Rust libraries for designing and working with zero knowledge succinct...

Say Hello To DataBend The Open Source Cloud Warehouse for Everyone

Databend is inspired by apache-arrow and allows you to scale your cloud warehousing, using off the shelf open source stacks & the ultra fast processing speeds you come to expect from say Bigquery

Say Hello To DataBend The Open Source Cloud Warehouse for Everyone

Bespoke protocol and high-level implementation of Non-fungible token (NFT) technology 🚀

This project is duel-licensed under both the Apache licenses, so feel free to use either at your discretion

Bespoke protocol and high-level implementation of Non-fungible token (NFT) technology 🚀

Bespoke protocol and high-level implementation of Non-fungible token (NFT) technology 🚀

This project is duel-licensed under both the Apache licenses, so feel free to use either at your discretion

Bespoke protocol and high-level implementation of Non-fungible token (NFT) technology 🚀
Facebook Instagram Twitter GitHub Dribbble
Privacy