Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Image processing Photoshop中色调/饱和度调整层的算法_Image Processing_Colors_Photoshop_Rgb_Hsl - Fatal编程技术网

Image processing Photoshop中色调/饱和度调整层的算法

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

有人知道Photoshop中的调整层是如何工作的吗?我需要从色调/饱和度调整层生成具有源图像和HSL值的结果图像。转换为RGB然后与源颜色相乘不起作用

或者,是否可以使用具有适当设置的混合模式(多重、屏幕、色调、饱和度、颜色、亮度等)的正常层替换色调/饱和度调整层? 如果是的话,那怎么办


谢谢你,我不知道。但其原理通常是:通过特定层的内部方法将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,但由于某些原因,它工作得不太好,然后我开始读一点,发现解决方案非常简单,有两件事必须做:

  • 当改变色调或饱和度时,仅替换原始图像的色调和饱和度,亮度保持原始图像的原样,这种混合方法称为10.2.4。亮度混合模式:

  • 当在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;
        }
    
    }
    
    //新色调,即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;
        }
    
    }