Image processing Photoshop中色调/饱和度调整层的算法
有人知道Photoshop中的调整层是如何工作的吗?我需要从色调/饱和度调整层生成具有源图像和HSL值的结果图像。转换为RGB然后与源颜色相乘不起作用 或者,是否可以使用具有适当设置的混合模式(多重、屏幕、色调、饱和度、颜色、亮度等)的正常层替换色调/饱和度调整层? 如果是的话,那怎么办Image processing Photoshop中色调/饱和度调整层的算法,image-processing,colors,photoshop,rgb,hsl,Image Processing,Colors,Photoshop,Rgb,Hsl,有人知道Photoshop中的调整层是如何工作的吗?我需要从色调/饱和度调整层生成具有源图像和HSL值的结果图像。转换为RGB然后与源颜色相乘不起作用 或者,是否可以使用具有适当设置的混合模式(多重、屏幕、色调、饱和度、颜色、亮度等)的正常层替换色调/饱和度调整层? 如果是的话,那怎么办 谢谢你,我不知道。但其原理通常是:通过特定层的内部方法将RGB图像转换为HSL/HSV;然后,根据指定的参数修改每个像素的HSL,并以RGB格式返回(用于显示)如此获得的结果 PaintShopPro7用于以3
谢谢你,我不知道。但其原理通常是:通过特定层的内部方法将RGB图像转换为HSL/HSV;然后,根据指定的参数修改每个像素的HSL,并以RGB格式返回(用于显示)如此获得的结果 PaintShopPro7用于以30°(IIRC)的离散增量分割H空间(假设范围为0..360),因此如果仅碰撞“黄色”,即仅考虑H分量值为45-75的像素进行操作 红色345..15,橙色15..45,黄色45..75,黄绿色75..105,绿色105..135,等等 if (h >= 45 && h < 75) s += s * yellow_percent; 如果(h>=45&&h<75) s+=s*黄色百分比; 还有其他可能性,例如应用衰减过滤器,如: /* 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; /*对于h=60,设m=1。。。线性下降到h=75m=0*/ m=1-abs(h-60)/15; if(m<0) m=0; s+=s*黄色×百分之d;
当选中“Colorize”复选框时,我已经为反向设计了计算。下面的所有代码都是伪代码 输入为:
- hueRGB,是HSV的RGB颜色(photoshop_色调,100100).ToRGB()
- 饱和度,即photoshop_饱和度/100.0(即0..1)
- 亮度,即photoshop_lightness/100.0(即-1..1)
- 值,即像素.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)
我已经弄明白了轻巧的原理 输入参数亮度b在[0,2]中,输出参数c(颜色通道)
但是,如果您选择某个时间间隔(例如,红色而不是主色),亮度的表现完全不同,更像是饱和度。您好,我编写了着色着色器,我的公式如下所示 inputRGB是应为单色的源图像
(r+g+b) * 0.333
colorRGB是您的目标颜色最终的结果是 伪代码:
finalRGB = inputRGB * (colorRGB + inputRGB * 0.5);
我认为它是快速有效的当选中“着色”复选框时,底层的亮度与色调和饱和度滑块的值相结合,并根据下面的公式从HSL转换为RGB。(亮度滑块只是将亮度重新映射到比例的一个子集,正如您从直方图中看到的那样;效果非常糟糕,我不明白为什么会有人使用它。)如果有人需要,我确实将@Roman Starkov solution翻译成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;
}
}
//新色调,即photoshop_色调(即0..360)
//新闻饱和度,即photoshop_饱和度/100.0(即0..1)
//newLightness,即photoshop_lightness/100.0(即-1..1)
//返回新颜色的rgb整数数组
私有静态int[]colorizeSinglePixel(int-originlPixel、int-newHue、float-newSaturation、float-newLightness)
{
float[]originalPixelHSV=新的float[3];
Color.colorToHSV(原始像素,原始像素HSV);
浮动原始像素椭圆度=原始像素hsv[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(新int[]{128128},hueRGB,newSaturation);
int blackColor[]=新int[]{Color.red(Color.BLACK)、Color.green(Color.BLACK)、Color.blue(Color.BLACK)};
int whileColor[]=新int[]{Color.red(Color.WHITE)、Color.green(Color.WHITE)、Color.blue(Color.WHITE)};
如果(新亮度=1)
{
返回whileColor;
}
else if(新亮度>=0)
{
返回blend3(黑色、彩色、whileColor(int)(2*(1-新亮度)*(原始像素亮度-1)+1));
}
其他的
{
返回blend3(黑色,彩色,whileColor,(int)((1+新亮度)*(原始像素亮度)-1));
}
}
私有静态int[]blend2(int[]左,int[]右,浮点位置)
{
返回新的int[]{(int)(左[0]*(1-pos)+右[0]*pos),(int)(左[1]*(1-pos)+右[1]*pos),(int)(左[2]*(1-pos)+右[2]*pos)};
}
私有静态int[]blend3(int[]左,int[]主,int[]右,int pos)
{
如果(位置<0)
{
回流混合器2(左、主、位置+1);
}
否则,如果(位置>0)
{
返回blend2(主、右、位置);
}
其他的
{
回水总管;
}
}
太好了,谢谢分享。我已经玩了你的代码,结果似乎比预期的要亮一点。然后我意识到这是因为这行2*(1+亮度)*(值)-1,如果我们不
(r+g+b) * 0.333
finalRGB = inputRGB * (colorRGB + inputRGB * 0.5);
//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;
}
}