簡體   English   中英

以rgb值查找比率

[英]Finding the ratio in an rgb value

我對編碼很新(今年年初開始),我在VB 2010 express中創建了一個程序,它為用戶提供的值創建了一個折線圖。

換句話說,我要求值並讓程序在畫布上創建矩形,每個項目的一個矩形添加到我的ArrayList

這部分代碼可以工作,現在我想要一個漸變顏色方案,所以每個矩形都有另一種顏色。 為此,我嘗試了這個:

Dim red As Integer = 254
Dim green As Integer = 141
Dim blue As Integer = 150

calcColor(red, green, blue)
Dim MyBrushColor As Color = Color.FromRgb(red, green, blue)

Private Sub calcColor(ByVal red As Integer, ByVal green As Integer, ByVal blue As Integer)

    If (red <= 0 Or green <= 0 Or blue <= 0) Then
        red = 254
        green = 141
        blue = 150
        red = red + 8
        green = green + 8
        blue = blue + 8
    End If
    If (red >= 254 Or green >= 141 Or blue >= 150) Then
        red = 254
        green = 141
        blue = 150
        red = red - 8
        green = green - 8
        blue = blue - 8
    End If
End Sub

每次只做-8和+8不會削減它,一旦它們達到零或其初始值,它們將有另一個比率..

作為一個非常缺乏經驗的編碼器,我不知道如何計算這個比率。 我只知道這是我想要的這種代碼。

不要重新發明輪子。 GDI +庫提供線性漸變畫筆。 您可以在兩者之間定義起點和終點以及顏色,並使用此畫筆進行繪畫。

示例(將在下面評論):

Dim bmp As New Bitmap(400, 400)
Using brush As Drawing2D.LinearGradientBrush = New Drawing2D.LinearGradientBrush(New Point(0, 0), _
                                                                                     New Point(400, 400), _
                                                                                     Color.Blue, _
                                                                                     Color.Red)
    Using p As New Pen(brush)
        Using g As Graphics = Graphics.FromImage(bmp)
            For i = 1 To 400 Step 10
                g.DrawRectangle(p, i - 5, i - 5, 10, 10)
            Next
        End Using
    End Using
End Using
If PictureBox1.Image IsNot Nothing Then PictureBox1.Image.Dispose()
PictureBox1.Image = bmp

首先,我創建一個位圖作為畫布( bmp )。 然后我創建了一個paint類的新對象。 在構造函數中,我提供了LinearGradientBrush類的對象,左上角有一個起點,右下角有一個終點,開頭的顏色為藍色,末尾的顏色為紅色。 然后我用這支筆在對角線上畫一排長方形作為參考。

在此輸入圖像描述

這個刷子也可以做更多。 它可以在平面上使用幾個點等,並為您進行顏色插值。 你只是用它畫畫。 有關更多詳細信息,請參閱MSDN: http//msdn.microsoft.com/de-de/library/system.drawing.drawing2d.lineargradientbrush.aspx

如果你遇到困難,請只看這個。 您將通過自己先嘗試自己了解更多信息。 你的老師可能已經看過了。

如果使用HSL顏色表示 ,則應該能夠通過在改變H(色調)時保持S(飽和度)和L(亮度)不變來獲得良好的效果。 您將需要編寫在RGB和HSL之間進行轉換的函數 - Internet上有很多實例,所以這是另一個:

Public Class ColourRepresentation

    ' Adapted from http://www.geekymonkey.com/Programming/CSharp/RGB2HSL_HSL2RGB.htm
    ' with conversion from C# to VB.NET by http://www.developerfusion.com/tools/convert/csharp-to-vb/

    Public Class HSLcolour
        Property H As Double
        Property S As Double
        Property L As Double

        Public Overrides Function ToString() As String
            Return String.Format("H={0}, S={1}, L={2}", H, S, L)
        End Function

    End Class

    ''' <summary>
    ''' Convert from HSL to RGB.
    ''' </summary>
    ''' <param name="c">An HSLcolour</param>
    ''' <returns>A System.Drawing.Color with A set to 255.</returns>
    ''' <remarks>H, S, L in the range [0.0, 1.0].</remarks>
    Public Shared Function HSLtoRGB(c As HSLcolour) As Color

        Dim r As Double = c.L
        Dim g As Double = c.L
        Dim b As Double = c.L

        Dim v As Double = If((c.L <= 0.5), (c.L * (1.0 + c.S)), (c.L + c.S - c.L * c.S))

        If v > 0 Then
            Dim m As Double = c.L + c.L - v
            Dim sv As Double = (v - m) / v
            c.H *= 6.0
            Dim sextant As Integer = CInt(Math.Truncate(c.H))
            Dim fract As Double = c.H - sextant
            Dim vsf As Double = v * sv * fract
            Dim mid1 As Double = m + vsf
            Dim mid2 As Double = v - vsf

            Select Case sextant
                Case 0, 6
                    r = v
                    g = mid1
                    b = m
                Case 1
                    r = mid2
                    g = v
                    b = m
                Case 2
                    r = m
                    g = v
                    b = mid1
                Case 3
                    r = m
                    g = mid2
                    b = v
                Case 4
                    r = mid1
                    g = m
                    b = v
                Case 5
                    r = v
                    g = m
                    b = mid2
            End Select
        End If

        Return Color.FromArgb(255, CByte(r * 255), CByte(g * 255), CByte(b * 255))

    End Function

    ' Given a Color (RGB Struct) in range of 0-255
    ' Return H,S,L in range of 0-1
    ''' <summary>
    ''' Convert from a Color to an HSLcolour.
    ''' </summary>
    ''' <param name="rgb">A System.Drawing.Color.</param>
    ''' <returns>An HSLcolour.</returns>
    ''' <remarks>Ignores Alpha value in the parameter.</remarks>
    Public Shared Function RGBtoHSL(rgb As Color) As HSLcolour
        Dim r As Double = rgb.R / 255.0
        Dim g As Double = rgb.G / 255.0
        Dim b As Double = rgb.B / 255.0

        Dim v As Double = Math.Max(r, g)
        v = Math.Max(v, b)
        Dim m As Double = Math.Min(r, g)
        m = Math.Min(m, b)
        Dim l As Double = (m + v) / 2.0

        If l <= 0.0 Then
            Return New HSLcolour With {.H = 0, .L = 0, .S = 0}
        End If

        Dim vm As Double = v - m
        Dim s As Double = vm

        If s > 0.0 Then
            s /= If((l <= 0.5), (v + m), (2.0 - v - m))
        Else
            Return New HSLcolour With {.H = 0, .L = 0, .S = 0}
        End If

        Dim r2 As Double = (v - r) / vm
        Dim g2 As Double = (v - g) / vm
        Dim b2 As Double = (v - b) / vm

        Dim h As Double = 0
        If r = v Then
            h = (If(g = m, 5.0 + b2, 1.0 - g2))
        ElseIf g = v Then
            h = (If(b = m, 1.0 + r2, 3.0 - b2))
        Else
            h = (If(r = m, 3.0 + g2, 5.0 - r2))
        End If

        h /= 6.0

        Return New HSLcolour With {.H = h, .L = l, .S = s}

    End Function

End Class

然后你需要一種改變色調的方法,我在這個繪制條形圖的粗略例子中使用過(我在一個Form上放了一個PictureBox):

Option Strict On
Option Infer On

Public Class Form1

    Dim rand As New Random
    Dim data As List(Of Double)

    Private Function DoubleModOne(value As Double) As Double
        While value > 1.0
            value -= 1.0
        End While
        While value < 0.0
            value += 1.0
        End While

        Return value

    End Function

    Sub DrawBars(sender As Object, e As PaintEventArgs)
        Dim target = DirectCast(sender, PictureBox)

        e.Graphics.Clear(Color.DarkGray)

        ' an approximation of the bar width
        'TODO: Improve the approximation.
        Dim barWidth As Integer = CInt(CDbl(target.Width) / data.Count)
        Dim maxBarHeight = target.Height

        Using br As New SolidBrush(Color.Black)
            Dim r As Rectangle

            'TODO: make it work for Color.Gainsboro
            Dim startColour = ColourRepresentation.RGBtoHSL(Color.Fuchsia)
            ' these components are broken out in case something needs to be done to them.
            Dim startColourH = startColour.H
            Dim startColourS = startColour.S
            Dim startColourL = startColour.L
            ' Using 1.0 as the quotient makes the colours go through the whole spectrum.
            Dim colourInc As Double = 1.0 / data.Count

            ' Only expects data to be in the range (0, 1).
            For i = 0 To data.Count - 1
                Dim thisHSLcolour As New ColourRepresentation.HSLcolour With {.H = DoubleModOne(startColourH + i * colourInc), .S = startColourS, .L = startColourL}
                br.Color = ColourRepresentation.HSLtoRGB(thisHSLcolour)
                r = New Rectangle(CInt(i * barWidth), CInt(data(i) * maxBarHeight), barWidth, maxBarHeight)
                e.Graphics.FillRectangle(br, r)
            Next

        End Using

    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim nBars = 100
        data = New List(Of Double)(nBars)
        For i = 0 To nBars - 1
            data.Add(rand.NextDouble())
        Next

        AddHandler PictureBox1.Paint, AddressOf DrawBars

    End Sub

End Class

導致:

在此輸入圖像描述

沒有人指責我選擇微妙的顏色,哈哈。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM