gtaylor / python-colormath

A python module that abstracts common color math operations. For example, converting from CIE L*a*b to XYZ, or from RGB to CMYK
python-colormath.readthedocs.org
BSD 3-Clause "New" or "Revised" License
456 stars 82 forks source link

[RFC] RGB clamping/upscaling API #97

Open ZipFile opened 5 years ago

ZipFile commented 5 years ago

One PR to (re)fix em all: #49, #64, #66, #87.

API around clamping and upscaling seems confusing for everyone, so here's proposal to fix this issue. Idea is to keep rgb color objects to represent values in a unified way and provide additional helpers to work with out-of-range values and scaling.

Core changes: sRGBColor(255, 123, 50, is_upscaled=True) becomes sRGBColor.new_from_upscaled(255, 123, 50) and

color = sRGBColor(-1.0, 0.5, 1.77)
print(color.clamped_rgb_r, color.clamped_rgb_g, color.clamped_rgb_b)
# output: 0 0.5 1

becomes:

color = sRGBColor(-1.0, 0.5, 1.77)
print(color.rgb_r, color.rgb_g, color.rgb_b)
# output: -1.0 0.5 1.77
color = color.clamped()
print(color.rgb_r, color.rgb_g, color.rgb_b)
# output: 0 0.5 1

Things to discus: colormath/color_conversions.py - In transformation chain math domain error occurs only for AdobeRGBColor and AppleRGBColor. Should it be documented? Seems like rgb clapping was added to fix #49, but as side effect we got contradiction with documentation and #87.

KelSolaar commented 5 years ago

I haven't looked yet at the PR but I think that the default behaviour should be to not clamp anything. Clamping values is really bad when doing gamut conversions. The math domain error on the power could be addressed elegantly by using a safe/symmetrical power such as the one we use in Colour.

ZipFile commented 5 years ago

Not really familiar with subject, but would safe/symmetrical power be correct? Avoiding stepping into complex numbers zone feels like there is some data loss possible, less drastic than clamping, though.

KelSolaar commented 5 years ago

but would safe/symmetrical power be correct?

Depends how you define correct. As you know, raising a negative number to a fractional power is undefined in R and it is problematic in many cases. The safe/symmetrical power will allow preserving the negative information which is important in a colour management chain, this is to say that anytime you clamp, you are destroying data.

ZipFile commented 4 years ago

Rebased with master.

I'm still not sure about safe/symmetrical power approach, though. Should I implement it for this PR?