以rgb值查找比率

时间:2014-05-23 17:36:32

标签: vb.net math colors rgb

我对编码很新(今年年初开始)并且我在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都不会削减它,一旦它们达到零或它们的初始值,它们就会有另一个比率......

作为一个非常缺乏经验的编码员,我不知道如何计算这个比率。我只知道它是我想要的这种代码。

2 个答案:

答案 0 :(得分:2)

不要重新发明轮子。 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类的对象,左上角有一个起点,右下角有一个终点,开头的颜色为蓝色,末尾的颜色为红色。 然后我用这支笔在对角线上画一排长方形作为参考。

enter image description here

这个画笔也可以做得更多。它可以在平面上使用几个点等,并为您进行颜色插值。你只是用它画画。有关详细信息,请参阅MSDN:http://msdn.microsoft.com/de-de/library/system.drawing.drawing2d.lineargradientbrush.aspx

答案 1 :(得分:0)

如果您遇到问题,请仅查看此内容。您将首先亲自尝试了解更多内容。你的老师可能已经看过了。

如果你使用HSL colour representation,你应该能够通过在改变H(色调)时保持S(饱和度)和L(亮度)不变来获得良好的效果。你需要编写函数来在RGB和HSL之间进行转换 - 互联网上有很多这样的实例,所以这是另一个:

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

然后你需要一种改变色调的方法,我在这个绘制条形图的粗略例子中使用过(我把一个PictureBox放在一个Form上):

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

导致:

enter image description here

没有人指责我选择微妙的颜色,哈哈。