
Introduction
This is a two for one article -- learn to build a brush of blended colors, and get a couple of cool color blending user controls in the process. There can be a lot of trial and error, tweaking the code and running it many times, to create a color blend. I thought it would be nice to have a control like those seen in drawing programs that would create the blend visually to get a proper placement of the colors. I will also try to explain the basics of making a color blended brush to paint with.
Build-A-Blend
Building a two color color blend is fairly simple. Using a LinearGradientBrush from the System.Drawing.Drawing2D namespace, you can paint an area with a blend from one color to another color.
Dim rect As New Rectangle(0, 0, 100, 100)
Using br As New LinearGradientBrush( _
rect, _
Color.White, _
Color.Black, _
LinearGradientMode.Horizontal)
g.FillRectangle(br, rect)
End Using
If you want more than two colors, a ColorBlend is needed. First, create an array of colors for each position in the blend. Then, create an array of values representing the position of each color in the color array. The first color has a position of 0, and the last color has a position of 1. All the other colors in between have a decimal position value between 0 and 1. After creating the arrays, assign them to the ColorBlend's Colors and Positions properties. Then, create the same LinearGradientBrush as before, setting the two colors to any color just as a placeholder. Set the Brush's InterpolationColors property to the ColorBlend just created to set the new multicolor blend. The LinearGradientBrush can be replaced with the PathGradientBrush for more complex shapes.
Dim blend As ColorBlend = New ColorBlend()
Dim bColors As Color() = New Color() { _
Color.Red, _
Color.Yellow, _
Color.Lime, _
Color.Cyan, _
Color.Blue, _
Color.Violet}
blend.Colors = bColors
Dim bPts As Single() = New Single() { _
0, _
0.327, _
0.439, _
0.61, _
0.777, _
1}
blend.Positions = bPts
Dim rect As New Rectangle(0, 0, 100, 100)
Using br As New LinearGradientBrush( _
rect, _
Color.White, _
Color.Black, _
LinearGradientMode.Horizontal)
br.InterpolationColors = blend
g.FillRectangle(br, rect)
End Using
ColorBlender Control
The ColorBlender User Control consists of a horizontal bar of color with a starting and ending color gradient. Clicking along the bar adds a new color pointer. The pointer can be dragged back and forth to any position along the bar with the left button, and removed with the right button. Click the dropdown to access preset color swatches, an owner-drawn combobox with all the known colors, and the ARGB color values that can be changed to alter the color and transparency of the selected pointer. There is a sample preview on the control to display the effects of changing the other options available to each brush type. The LinearGradientBrush paints the ColorBlend on a line from point A to point B. The PathGradientBrush paints the blend around a path. The control’s properties are accessible to recreate the blend as needed outside the control. Note: The separate ColorBlenderLite control is the same except it does not have the sample preview and brush properties built in.
Events
Control Properties
Here is a list of the primary properties:
BlendColors
Array of colors used in ColorBlend.
BlendPositions
Array of color positions used in ColorBlend.
BlendGradientType
Type of brush used to paint the ColorBlend - Linear or Path.
BlendGradientMode
Type of linear gradient color blend.
BlendPathShape
Shape of path for the ColorBlend - Rectangle, Ellipse, Triangle, Polygon.
BlendPathCenterPoint
Position of the center of the path ColorBlend.
BarHeight
Height of color blender bar.
Methods
Methods to use outside the control. Currently, just one to convert the center point to another area's dimensions.
Mouse Events
Track if the cursor is over a pointer to select or add a pointer, or to adjust the position of the center point of a path.
Drawing
Contains the routines to draw the pointers, build the brushes, and build the ColorBlend.
Painting
Paint the control to a Bitmap to create a buffer, eliminating flicker.
Protected Overrides Sub _
OnPaintBackground(ByVal e As System.Windows.Forms.PaintEventArgs)
End Sub
Protected Overrides Sub _
OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
BuildBlend()
Dim bitmapBuffer As Bitmap = _
New Bitmap(Me.ClientSize.Width, Me.ClientSize.Height)
Dim g As Graphics = Graphics.FromImage(bitmapBuffer)
g.Clear(Me.BackColor)
g.SmoothingMode = SmoothingMode.AntiAlias
Dim barRect As Rectangle = _
New Rectangle(10, 0, Me.ClientSize.Width - 20, BarHeight)
Dim br As Brush = LinearBrush(barRect, LinearGradientMode.Horizontal)
g.FillRectangle(br, barRect)
Dim sampleRect As Rectangle = _
New Rectangle(Me.Width - 85, BarHeight + 20, 75, 75)
If BlendGradientType = eBlendGradientType.Linear Then
br = LinearBrush(sampleRect, GetBrushMode)
Else
br = PathBrush(sampleRect)
g.DrawString(String.Format("X: {0} Y: {1}", _
BlendPathCenterPoint.X - (Width - 85), _
BlendPathCenterPoint.Y - (BarHeight + 20)), _
New Font("Arial", 8, FontStyle.Regular), _
Brushes.Black, Width - 85, BarHeight + 100)
End If
g.FillRectangle(br, sampleRect)
Using pn As New Pen(Color.Gray, 1)
pn.DashStyle = DashStyle.Dash
g.DrawLine(pn, 10, BarHeight + 7, _
Me.ClientSize.Width - 15, BarHeight + 7)
pn.Color = Color.Black
pn.DashStyle = DashStyle.Solid
DrawPointer(g, StartPointer.pColor, 0, StartPointer.pIsCurr)
DrawPointer(g, EndPointer.pColor, 1, EndPointer.pIsCurr)
If MiddlePointers IsNot Nothing Then
For I As Integer = 1 To MiddlePointers.Count
DrawPointer(g, MiddlePointers(I).pColor, _
MiddlePointers(I).pPos, I = CurrPointer)
Next
End If
End Using
e.Graphics.DrawImage(bitmapBuffer.Clone, 0, 0)
bitmapBuffer.Dispose()
br.Dispose()
g.Dispose()
End Sub
SortCollection
Use the CallByName function to sort the collection of pointers by the pPos property value.
Controls
Contains the events for the controls on the ColorBlender control.
ColorBox
Contains the DrawItem event for the owner-drawn combobox to list the known colors.
Pointer
The Pointer class contains three properties.
pPos - Position of the color.
pColor - Color at the position value.
pIsCurr - The pointer currently selected.
History