Photoshopで調整レイヤーがどのように機能するか知っている人はいますか? ソース画像と色相/彩度調整レイヤーからの HSL 値を持つ結果画像を生成する必要があります。RGB に変換してから元の色と乗算しても機能しません。
または、色相/彩度調整レイヤーを、適切に設定されたブレンド モード (倍率、スクリーン、色相、彩度、色、明度など) を持つ通常のレイヤーに置き換えることは可能ですか? もしそうなら、どのように?
ありがとう
Photoshopで調整レイヤーがどのように機能するか知っている人はいますか? ソース画像と色相/彩度調整レイヤーからの HSL 値を持つ結果画像を生成する必要があります。RGB に変換してから元の色と乗算しても機能しません。
または、色相/彩度調整レイヤーを、適切に設定されたブレンド モード (倍率、スクリーン、色相、彩度、色、明度など) を持つ通常のレイヤーに置き換えることは可能ですか? もしそうなら、どのように?
ありがとう
「Colorize」チェックボックスがチェックされているときの計算をリバースエンジニアリングしました。以下のコードはすべて疑似コードです。
入力は次のとおりです。
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がどのように機能するかを理解しました。
入力パラメーターの明るさ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 のようになります。
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;
必要に応じて@Roman StarkovソリューションをJavaに変換しましたが、何らかの理由でうまく機能しませんでした。少し読み始めて、解決策が非常に簡単であることがわかりました.2つのことを行う必要があります。
色相または彩度を変更すると、元の画像が色相と彩度のみに置き換えられ、明度は元の画像のままになります。このブレンド メソッドは 10.2.4 と呼ばれます。光度ブレンド モード: https://www.w3.org/TR/compositing-1/#backdrop
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;
}
}