16

Photoshopで調整レイヤーがどのように機能するか知っている人はいますか? ソース画像と色相/彩度調整レイヤーからの HSL 値を持つ結果画像を生成する必要があります。RGB に変換してから元の色と乗算しても機能しません。

または、色相/彩度調整レイヤーを、適切に設定されたブレンド モード (倍率、スクリーン、色相、彩度、色、明度など) を持つ通常のレイヤーに置き換えることは可能ですか? もしそうなら、どのように?

ありがとう

4

6 に答える 6

12

「Colorize」チェックボックスがチェックされているときの計算をリバースエンジニアリングしました。以下のコードはすべて疑似コードです。

入力は次のとおりです。

  • hueRGBRGB カラーです。HSV(photoshop_hue, 100, 100).ToRGB()
  • 彩度photoshop_saturation / 100.0つまり (つまり 0..1)
  • 明度photoshop_lightness / 100.0つまり (-1..1)
  • value、これはpixel.ToHSV().Value0..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
于 2012-02-07T14:01:51.553 に答える
3

Lightnessがどのように機能するかを理解しました。

入力パラメーターの明るさ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 の代わりに Reds)、Lightness はまったく異なる動作をし、Saturation のようになります。

于 2013-11-18T22:29:44.447 に答える
2

Photoshop、わかりません。しかし、理論は通常次のとおりです。RGB イメージは、特定のレイヤーの内部メソッドによって HSL/HSV に変換されます。次に、各ピクセルの HSL が指定されたパラメーターに従って変更され、そのようにして得られた結果が (表示用に) RGB で返されます。

PaintShopPro7 は、H 空間 (0..360 の範囲を想定) を 30° (IIRC) の個別の増分で分割していました。操作の対象と見なされます。

赤 345..15、オレンジ 15..45、黄 45..75、黄緑 75..105、緑 105..135 など

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

次のように、フォールオフ フィルターを適用するなど、別の方法もあります。

/* h=60 の場合、m=1... とし、h=75 m=0 まで直線的に低下します。*/
m = 1 - abs(h - 60) / 15;
もし (m < 0)
        m = 0;
s += s * yellow_percent * d;
于 2010-12-10T02:57:16.943 に答える
1

必要に応じて@Roman StarkovソリューションをJavaに変換しましたが、何らかの理由でうまく機能しませんでした。少し読み始めて、解決策が非常に簡単であることがわかりました.2つのことを行う必要があります。

  1. 色相または彩度を変更すると、元の画像が色相と彩度のみに置き換えられ、明度は元の画像のままになります。このブレンド メソッドは 10.2.4 と呼ばれます。光度ブレンド モード: https://www.w3.org/TR/compositing-1/#backdrop

  2. Photoshop で明度を変更する場合、スライダーは、HSL で白または黒の色を得るために、元の明度に追加または元の明度から差し引く必要があるパーセンテージを示します。

例: 元のピクセルが 0.7 明度で、明度スライダー = 20 の場合、1 にするにはさらに 0.3 明度が必要です。

そのため、元のピクセルの明度に追加する必要があります: 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;
    }

}
于 2020-07-02T10:44:40.640 に答える