Algorithm for Hue/Saturation Adjustment Layer from Photoshop

拟墨画扇 提交于 2019-12-02 17:19:26

I've reverse-engineered the computation for when the "Colorize" checkbox is checked. All of the code below is pseudo-code.

The inputs are:

  • hueRGB, which is an RGB color for HSV(photoshop_hue, 100, 100).ToRGB()
  • saturation, which is photoshop_saturation / 100.0 (i.e. 0..1)
  • lightness, which is photoshop_lightness / 100.0 (i.e. -1..1)
  • value, which is the pixel.ToHSV().Value, scaled into 0..1 range.

The method to colorize a single pixel:

color = blend2(rgb(128, 128, 128), hueRGB, saturation);

if (lightness <= -1)
    return black;
else if (lightness >= 1)
    return white;

else if (lightness >= 0)
    return blend3(black, color, white, 2 * (1 - lightness) * (value - 1) + 1)
else
    return blend3(black, color, white, 2 * (1 + lightness) * (value) - 1)

Where blend2 and blend3 are:

blend2(left, right, pos):
    return rgb(left.R * (1-pos) + right.R * pos, same for green, same for blue)

blend3(left, main, right, pos):
    if (pos < 0)
        return blend2(left, main, pos + 1)
    else if (pos > 0)
        return blend2(main, right, pos)
    else
        return main

I have figured out how Lightness works.

The input parameter brightness b is in [0, 2], Output is c (color channel).

if(b<1) c = b * c;
else    c = c + (b-1) * (1-c);

Some tests:

b = 0  >>>  c = 0  // black
b = 1  >>>  c = c  // same color
b = 2  >>>  c = 1  // white

However, if you choose some interval (e.g. Reds instead of Master), Lightness behaves completely differently, more like Saturation.

Photoshop, dunno. But the theory is usually: The RGB image is converted to HSL/HSV by the particular layer's internal methods; each pixel's HSL is then modified according to the specified parameters, and the so-obtained result is being provided back (for displaying) in RGB.

PaintShopPro7 used to split up the H space (assuming a range of 0..360) in discrete increments of 30° (IIRC), so if you bumped only the "yellows", i.e. only pixels whose H component was valued 45-75 would be considered for manipulation.

reds 345..15, oranges 15..45, yellows 45..75, yellowgreen 75..105, greens 105..135, etc.

if (h >= 45 && h < 75)
        s += s * yellow_percent;

There are alternative possibilities, such as applying a falloff filter, as in:

/* For h=60, let m=1... and linearly fall off to h=75 m=0. */
m = 1 - abs(h - 60) / 15;
if (m < 0)
        m = 0;
s += s * yellow_percent * d;

Hello I wrote colorize shader and my equation is as folows

inputRGB is the source image which should be in monochrome

(r+g+b) * 0.333

colorRGB is your destination color
finalRGB is the result

pseudo code:

finalRGB = inputRGB * (colorRGB + inputRGB * 0.5);

I think it's fast and efficient

Russell Cottrell

When the “Colorize” checkbox is checked, the lightness of the underlying layer is combined with the values of the Hue and Saturation sliders and converted from HSL to RGB according to the equations at https://en.wikipedia.org/wiki/HSL_and_HSV#From_HSL . (The Lightness slider just remaps the lightness to a subset of the scale as you can see from watching the histogram; the effect is pretty awful and I don’t see why anyone would ever use it.)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!