GNOME Bugzilla – Bug 795207
Add color space to blend(gradient) tool options
Last modified: 2018-04-17 20:03:44 UTC
We currently only do gradient interpolation in sRGB, or "R'G'B'A float", mitch has patches around that in part make this configurable. At first just offering interpolation in linear-RGB / "RGBA float". This would get rid of bad color interpolation between for instance red and green - and matches the current scope of CSS/SVG gradients. This should be done as a tool option and not as a property of the gradient, we do not want linear foreground-to-transparent and a perceptual foreground-to-transparent as well as black/to white variants of each. Recently the desire for perceptual luminance with linear RGB blending has also been raised, adding that now or in the future would cause the number of similar-ish gradients on need to distinguish to explode further. 18:36 < linux_dr> mitch, pippin: Sorry, back... can’t talk long, by let me see if I can clarify... my method involves two colorspace transforms, (I’m using sRGB for both of them) and a brightness conversion (I’m using the Y luminance value from YCrCb)... the idea is like this: 1) linear (from whatever source colorspace) is the correct way to mix colors, so all color mixing is converted from origin colorspace to linear and back before blending. 2) the 18:36 < linux_dr> purpose of gamma in the first place, is to spread out the distinct intensity values so that they are concentrated where the human vision system is most sensitive to distinctions... as a result, a gamma space gradient looks much more even to humans than a linear one, so use a second colorspace transform to represent evenness of a transform... as I said before, I’m using sRGB for both of these... in order to use our second color space to 18:36 < linux_dr> even out values, we need a way of converting a color to a brightness... you could use root mean squared or “value” from HSV, etc... I chose luminance (Y) from YCrCb... so... I convert both start and end color into linear color space (with the first sRGB colorspace transform) then determine the “brightness” of each color. If the brightnesses are the same, fall back to standard linear interpolation... OTHERWISE, use a reverse of 18:36 < linux_dr> the second colorspace to turn the “brightness” back into a gamma value... and do a gamma space interpolation of the gamma value... translate and stretch the gamma brightness to the 0 to 1 range... then use that as your parametric value in the linear space gradient before the conversion to brightness... then convert the result back to the native colorspace... does that make any sense? This is something that can also be achieved by using CIE Lab, for comparison of various color spaces see this: http://howaboutanorange.com/blog/2011/08/10/color_interpolation/ Adding the ability to override things and even use CIE Lch would provide a way to solve https://bugzilla.gnome.org/show_bug.cgi?id=753245 , perhaps a gradient can specify an override to always use a specific format, thus enabling having rainbow hue-gradients using a simpler construct.
Regarding "looks more uniform to people", yes, in many cases a perceptually uniform RGB gradient is a lot prettier and also more useful than a linear gamma "radiometrically correct" gradient. But which type of gradient is "better" at any given time depends on the task at hand. I don't understand exactly what linux_dr wants to do in the proposed gradient code described above. But currently the YCbCr code in babl/GEGL/GIMP (well, the actual code is in babl) uses hard-coded Y values. So writing new code written using YCbCr might make the future move from "sRGB" to "AnyRGB" more difficult. There's always "Y" from XYZ for the actual RGB color space in question, which in babl isn't hard-coded any more, though it is still hard-coded to sRGB in GIMP in libgimpcolor/gimprgb.h. The ability to draw gradients using LCh and even Lab would be nice. Currently to make approximation of LCh gradients, I've been using selections to make short segments of "RGB" or "HSV" gradients, with the endpoints of each short segment picked using the LCh color picker. But this is very time-consuming and only produces an "approximately LCh" gradient.
Initial patch is almost ready, making this a blocker.
*** Bug 735897 has been marked as a duplicate of this bug. ***
Step one: commit bf49b476209ed8350438fa496e7338c172b9b3b3 Author: Michael Natterer <mitch@gimp.org> Date: Fri Apr 13 22:33:16 2018 +0200 Bug 795207 - Add color space to blend(gradient) tool options First WIP commit, adds: - enum GimpGradientBlendColorSpace { RGB_PERCEPTUAL, RGB_LINEAR } - linear blending mode for gradient segments - tool options GUI for the blend and paint tools which use gradients app/actions/gradient-editor-commands.c | 2 + app/core/gimpgradient.c | 133 +++++++++++++++++++++------------- app/core/gimpgradient.h | 6 ++ app/operations/gimpoperationblend.c | 68 +++++++++++------ app/operations/gimpoperationblend.h | 25 ++++--- app/paint/gimppaintoptions.c | 25 ++++++- app/paint/gimppaintoptions.h | 5 +- app/pdb/gradient-cmds.c | 54 ++++++++++---- app/pdb/gradients-cmds.c | 12 ++- app/tools/gimpblendoptions.c | 10 +++ app/tools/gimpblendoptions.h | 2 +- app/tools/gimpblendtool-editor.c | 7 +- app/tools/gimppaintoptions-gui.c | 16 +++- app/widgets/gimpgradienteditor.c | 8 +- app/widgets/gimpgradienteditor.h | 2 + app/widgets/gimpgradientselect.c | 4 +- app/widgets/gimpviewablebox.c | 47 +++++++++++- app/widgets/gimpviewablebox.h | 4 +- app/widgets/gimpviewrenderergradient.c | 25 ++++++- app/widgets/gimpviewrenderergradient.h | 24 +++--- libgimp/gimpenums.c.tail | 2 + libgimpbase/gimpbase.def | 1 + libgimpbase/gimpbaseenums.c | 30 ++++++++ libgimpbase/gimpbaseenums.h | 12 +++ pdb/enums.pl | 8 ++ pdb/groups/gradient.pdb | 54 ++++++++++---- pdb/groups/gradients.pdb | 12 ++- 27 files changed, 445 insertions(+), 153 deletions(-)
Linear RGB, Perceptual RGB, and CIE LAB are now available color space options. Closing as fixed. For CIE LCH, please file a separate bug report, preferably on gitlab once we move there :)