Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Algorithm for Hue/Saturation Adjustment Layer from Photoshop

Does anyone know how adjustment layers work in Photoshop? I need to generate a result image having a source image and HSL values from Hue/Saturation adjustment layer. Conversion to RGB and then multiplication with the source color does not work.

Or is it possible to replace Hue/Saturation Adjustment Layer with normal layers with appropriately set blending modes (Mulitiply, Screen, Hue, Saturation, Color, Luminocity,...)? If so then how?

Thanks

like image 226
lechec Avatar asked Dec 10 '10 00:12

lechec


3 Answers

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
like image 173
Roman Starkov Avatar answered Nov 14 '22 01:11

Roman Starkov


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.

like image 23
Ivan Kuckir Avatar answered Nov 14 '22 01:11

Ivan Kuckir


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;
like image 2
user502515 Avatar answered Nov 14 '22 02:11

user502515