2012-11-11 109 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

搜索這裏RGB到HSL,你會發現關於這個專題的許多職位。 – 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

我假設你玩的是參數,你應該能夠得到完美的匹配。試着改變alphareducedSaturation2(目前= 40)和GetSaturation分頻器(目前爲1.3)

這裏是我的代碼示例:

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),所以你不能再玩了。這是alpha可以提供幫助的地方。實際上,你可以使用全部三個來達到預期的效果。 – Neolisk

9

對於那些想避免一切轉換爲HSL/HSV和背部,這個工程相當不錯(如果不正確取決於人們認爲什麼是「正確的」去飽和圖像是):

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圖像和灰度圖像之間的線性插值。 –

相關問題