2012-11-11 18 views
7

私は正しい色の用語を使用していないかもしれませんが、基本的には添付されている画像に似た色をスケールすることができます。私はこれを行うために彩度を探していました。正しいバージョンが左の彩度の低いバージョンであるように見えます。色を不飽和化する方法は?

enter image description here

私は(私が見つけた)、これをしようとしていたが、それは全く正しい見ていない:

Public Shared Function GetDesaturatedColor(color As Color) As Color 
    Const kValue As Double = 0.01R 

    Dim greyLevel = (color.R * 0.299R) + _ 
        (color.G * 0.587R) + _ 
        (color.B * 0.144R) 

    Dim r = greyLevel * kValue + (color.R) * (1 - kValue) 
    Dim g = greyLevel * kValue + (color.G) * (1 - kValue) 
    Dim b = greyLevel * kValue + (color.B) * (1 - kValue) 

    ' ColorUtils.ToByte converts the double value 
    ' to a byte safely 
    Return color.FromArgb(255, _ 
          ColorUtils.ToByte(r), _ 
          ColorUtils.ToByte(g), _ 
          ColorUtils.ToByte(b)) 
End Function 

誰もがこれを行うことができますいくつかのアルゴリズムを知っていますか?

+1

検索をして、トピックに関する多くの記事があります:(正しく1が「正しい」彩度画像が考えるものに依存していない場合)、これは合理的にうまく機能します。 – Brad

答えて

2

@Bradは投稿のコメントに記載されているように、まずRGBからHSL or HSVに色を変換します。そこから、彩度を減らすのは簡単です。彩度を値で減算または除算するだけです。

その後、HSL/HSVカラーをRGBに変換し直して使用できます。

How to change RGB color to HSV?には、Manipulating colors in .netのようにこれを行う方法の良い例があります。

2

彩度を下げるだけでは、画像に示された結果を得るには不十分であることが実験からわかります。私はOPの質問からの色を以下のコードで使用しました。あなただけの彩度を下げる場合は、ここであなたが得るものです:

enter image description here

あなたはまた、新色のアルファ/不透明度を下げる場合は、あなたがより良い結果を達成することができます:私は

enter image description here

をあなたがパラメータで遊ぶならば、あなたは完璧なマッチを得ることができるはずです。ここで

(現在は1.3 =)reducedSaturation2ためalphaを変更してみてください(現在= 40)とGetSaturationディバイダ私のコードサンプルです:HSL/HSVとバックにすべてを変換しないようにしたいという人のために

Public Function HSVToColor(ByVal H As Double, ByVal S As Double, ByVal V As Double) As Color 
    Dim Hi As Integer = (H/60) Mod 6 
    Dim f As Double = H/60 Mod 1 
    Dim p As Integer = V * (1 - S) * 255 
    Dim q As Integer = V * (1 - f * S) * 255 
    Dim t As Integer = V * (1 - (1 - f) * S) * 255 
    Select Case Hi 
    Case 0 : Return Color.FromArgb(V * 255, t, p) 
    Case 1 : Return Color.FromArgb(q, V * 255, p) 
    Case 2 : Return Color.FromArgb(p, V * 255, t) 
    Case 3 : Return Color.FromArgb(p, V * 255, q) 
    Case 4 : Return Color.FromArgb(t, p, V * 255) 
    Case 5 : Return Color.FromArgb(V * 255, q, p) 
    End Select 
End Function 

Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click 
    Dim normalSaturation As Color = Color.FromArgb(255, 216, 53, 45) 
    Me.CreateGraphics.FillRectangle(New SolidBrush(normalSaturation), 100, 0, 100, 100) 
    Dim reducedSaturation As Color = HSVToColor(normalSaturation.GetHue, normalSaturation.GetSaturation/1.3, normalSaturation.GetBrightness) 
    Dim reducedSaturation2 As Color = Color.FromArgb(40, reducedSaturation) 
    Me.CreateGraphics.FillRectangle(New SolidBrush(reducedSaturation2), 0, 0, 100, 100) 
End Sub 
+1

私もこれに気付きました。私が解決しようとしたのは、彩度を下げて明るさ(値)を上げることでした。私は私の絵によく似た何かを得ることができました。私はあなたのお試しになりますが、ありがとうございます。 – test

+0

@reedparkes:私はbrigthnessで遊ぼうとしました - 問題はそれが十分に高い(= 255)になっているので、もうあなたはそれを上げることができません。これはアルファが助けることができるところです。実際には、おそらく3つすべてを使用して、望ましい結果を達成することができます。 – Neolisk

9

、 HSLに、ここでRGB用

f = 0.2; // desaturate by 20% 
L = 0.3*r + 0.6*g + 0.1*b; 
new_r = r + f * (L - r); 
new_g = g + f * (L - g); 
new_b = b + f * (L - b); 
+0

チャームのように働いた – CatalinBerta

+0

このアルゴリズムの説明はなんですか?それの名前はありますか?イメージ処理atmを学ぼうとしています。 – kosinix

+0

緑、赤、青が画像の[Luma](https://en.wikipedia.org/wiki/Grayscale#Luma_coding_in_video_systems)に対応するという共通の仮定を使用して、r、g、bをグレースケールに変換しています。だから 'L'はグレースケール画像で、' f'は入力RGB画像とそのグレースケール画像の間をちょうど直線的に補間しています。 –

関連する問題