有人知道调整图层在 Photoshop 中是如何工作的吗?我需要从色相/饱和度调整层生成具有源图像和 HSL 值的结果图像。转换为 RGB,然后与源颜色相乘不起作用。
或者是否可以使用适当设置混合模式(倍增、屏幕、色相、饱和度、颜色、亮度……)的普通图层替换色相/饱和度调整图层?如果是,那怎么办?
谢谢
有人知道调整图层在 Photoshop 中是如何工作的吗?我需要从色相/饱和度调整层生成具有源图像和 HSL 值的结果图像。转换为 RGB,然后与源颜色相乘不起作用。
或者是否可以使用适当设置混合模式(倍增、屏幕、色相、饱和度、颜色、亮度……)的普通图层替换色相/饱和度调整图层?如果是,那怎么办?
谢谢
我已经对选中“着色”复选框时的计算进行了逆向工程。下面的所有代码都是伪代码。
输入是:
HSV(photoshop_hue, 100, 100).ToRGB()
photoshop_saturation / 100.0
(即0..1)photoshop_lightness / 100.0
(即-1..1)pixel.ToHSV().Value
,缩放到 0..1 范围内。为单个像素着色的方法:
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)
地点blend2
和地点blend3
:
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
我已经弄清楚Lightness是如何工作的。
输入参数brightness b在[0, 2]中,输出为c(颜色通道)。
if(b<1) c = b * c;
else c = c + (b-1) * (1-c);
一些测试:
b = 0 >>> c = 0 // black
b = 1 >>> c = c // same color
b = 2 >>> c = 1 // white
但是,如果您选择某个间隔(例如,红色而不是 Master),Lightness 的表现完全不同,更像是 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;
您好,我写了着色着色器,我的方程式如下
inputRGB 是应该是单色的源图像
(r+g+b) * 0.333
colorRGB 是您的目标颜色
finalRGB 是结果
伪代码:
finalRGB = inputRGB * (colorRGB + inputRGB * 0.5);
我认为它快速有效
如果有人需要,我确实将@Roman Starkov 解决方案翻译成java,但由于某种原因它效果不佳,然后我开始阅读一点,发现解决方案非常简单,有两件事要做:
当改变色调或饱和度时,只替换原始图像的色调和饱和度,亮度保持原样,这种混合方法称为 10.2.4。亮度混合模式: https ://www.w3.org/TR/compositing-1/#backdrop
在 Photoshop 中更改亮度时,滑块指示我们需要在原始亮度中添加或减去多少百分比才能在 HSL 中获得白色或黑色。
例如:如果原始像素是 0.7 亮度并且亮度滑块 = 20,那么我们需要更多的 0.3 亮度才能达到 1
所以我们需要添加到原始像素亮度:0.7 + 0.2*0.3;这将是新像素的新混合亮度值。
@Roman Starkov 解决方案 Java 实现:
//newHue, which is photoshop_hue (i.e. 0..360)
//newSaturation, which is photoshop_saturation / 100.0 (i.e. 0..1)
//newLightness, which is photoshop_lightness / 100.0 (i.e. -1..1)
//returns rgb int array of new color
private static int[] colorizeSinglePixel(int originlPixel,int newHue,float newSaturation,float newLightness)
{
float[] originalPixelHSV = new float[3];
Color.colorToHSV(originlPixel,originalPixelHSV);
float originalPixelLightness = originalPixelHSV[2];
float[] hueRGB_HSV = {newHue,100.0f,100.0f};
int[] hueRGB = {Color.red(Color.HSVToColor(hueRGB_HSV)),Color.green(Color.HSVToColor(hueRGB_HSV)),Color.blue(Color.HSVToColor(hueRGB_HSV))};
int color[] = blend2(new int[]{128,128,128},hueRGB,newSaturation);
int blackColor[] = new int[]{Color.red(Color.BLACK),Color.green(Color.BLACK),Color.blue(Color.BLACK)};
int whileColor[] = new int[]{Color.red(Color.WHITE),Color.green(Color.WHITE),Color.blue(Color.WHITE)};
if(newLightness <= -1)
{
return blackColor;
}
else if(newLightness >=1)
{
return whileColor;
}
else if(newLightness >=0)
{
return blend3(blackColor,color,whileColor, (int) (2*(1-newLightness)*(originalPixelLightness-1) + 1));
}
else
{
return blend3(blackColor,color,whileColor, (int) ((1+newLightness)*(originalPixelLightness) - 1));
}
}
private static int[] blend2(int[] left,int[] right,float pos)
{
return new int[]{(int) (left[0]*(1-pos)+right[0]*pos),(int) (left[1]*(1-pos)+right[1]*pos),(int) (left[2]*(1-pos)+right[2]*pos)};
}
private static int[] blend3(int[] left,int[] main,int[] right,int pos)
{
if(pos < 0)
{
return blend2(left,main,pos+1);
}
else if(pos > 0)
{
return blend2(main,right,pos);
}
else
{
return main;
}
}
当“着色”复选框被选中时,底层的亮度与色调和饱和度滑块的值相结合,并根据https://en.wikipedia.org/wiki/HSL_and_HSV上的公式从 HSL 转换为 RGB #From_HSL。(亮度滑块只是将亮度重新映射到比例的子集,从直方图可以看出;效果非常糟糕,我不明白为什么有人会使用它。)