2012-11-11 34 views
7

Tôi có thể không sử dụng thuật ngữ màu chính xác nhưng tôi muốn cơ bản có thể mở rộng màu tương tự như hình ảnh đính kèm. Tôi đã tìm kiếm sự bão hòa để làm điều này, vì nó xuất hiện đúng phiên bản chỉ là một phiên bản ít bão hòa phải của bên trái.Làm thế nào để Desaturate một màu?

enter image description here

Tôi đã cố gắng này (mà tôi tìm thấy) nhưng nó không phải là tìm cách chính xác tại tất cả:

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 

Có ai biết về một số thuật toán có thể làm điều này?

+1

Tìm ở đây RGB to HSL và bạn sẽ tìm thấy nhiều bài viết về chủ đề này. – Brad

Trả lời

2

Như @Brad đã đề cập trong nhận xét cho bài đăng của bạn, bước đầu tiên của bạn là chuyển đổi màu từ RGB thành HSL or HSV. Từ đó, giảm độ bão hòa là tầm thường - chỉ cần trừ hoặc chia độ bão hòa bằng một giá trị để giảm nó.

Sau đó, chuyển đổi màu HSL/HSV của bạn trở lại thành RGB và sẵn sàng để sử dụng.

How to change RGB color to HSV? có ví dụ tốt về cách thực hiện điều này, cũng như Manipulating colors in .net.

2

Nó xuất hiện bằng thử nghiệm mà chỉ giảm độ bão hòa là không đủ để có được kết quả được hiển thị trong hình. Tôi đã sử dụng các màu từ câu hỏi của OP trong đoạn mã dưới đây. Nếu bạn chỉ làm giảm độ bão hòa, đây là những gì bạn nhận được:

enter image description here

Nếu bạn cũng giảm alpha/độ mờ đục của màu sắc mới, bạn có thể đạt được một kết quả tốt hơn:

enter image description here

tôi giả sử nếu bạn chơi với các thông số, bạn sẽ có thể có được một trận đấu hoàn hảo. Hãy thử thay đổi alpha cho reducedSaturation2 (hiện tại = 40) và GetSaturation chia (hiện tại = 1.3)

Đây là mẫu mã của tôi:

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

Tôi cũng nhận thấy điều này. Cách tôi cố gắng giải quyết nó là giảm độ bão hòa và tăng độ sáng (giá trị). Tôi đã có thể nhận được một cái gì đó decently tương tự như hình ảnh của tôi. Tôi sẽ thử của bạn mặc dù, cảm ơn. – test

+0

@reedparkes: Tôi đã cố gắng chơi với sự lốm đốm - vấn đề là ở một số nó đủ cao (= 255), vì vậy bạn không thể lên nó nữa. Đây là nơi alpha có thể giúp. Trên thực tế, bạn có thể sử dụng cả ba để đạt được kết quả mong muốn. – Neolisk

9

Đối với những người muốn tránh chuyển đổi tất cả mọi thứ để HSL/HSV và lưng, điều này hoạt động khá tốt (nếu không chính xác tùy thuộc vào những gì người cho rằng hình ảnh bão hòa "chính xác" là):

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

Làm việc như một sự quyến rũ – CatalinBerta

+0

Whats lời giải thích cho thuật toán này? Có tên cho nó không? Đang cố gắng tìm hiểu quá trình xử lý hình ảnh. – kosinix

+0

Điều này chuyển đổi r, g, b thành thang độ xám bằng cách sử dụng giả định chung là xanh lục, đỏ và xanh dương tương ứng với [Luma] (https://en.wikipedia.org/wiki/Grayscale#Luma_coding_in_video_systems) của một tỷ lệ giảm hình ảnh tương ứng . Vì vậy, 'L' là một hình ảnh thang độ xám và sau đó' f' chỉ là nội suy tuyến tính giữa hình ảnh RGB đầu vào và hình ảnh thang độ xám đó. –

Các vấn đề liên quan