原文: http://zetcode.com/gui/vbwinforms/painting/

在 Visual Basic Winforms 教程的这一部分中,我们将进行绘图。 当我们想要更改或增强现有控件时,将使用绘图。 或者,如果我们要从头开始创建自定义控件。 要进行绘图,我们使用 Winforms 库提供的绘图 API。 绘图是在一种方法中完成的,我们将其插入Paint事件。

System.Drawing名称空间提供对GDI+基本图形功能的访问。 System.Drawing.Drawing2DSystem.Drawing.ImagingSystem.Drawing.Text命名空间中提供了更高级的功能。 Graphics类提供了在表单上绘图的方法。

HatchBrush

HatchBrush对象用于填充形状的内部。 我们可以使用几种内置模式。

  1. ' ZetCode Mono Visual Basic Winforms tutorial
  2. '
  3. ' This program draws nine rectangles.
  4. ' The interiors are filled with
  5. ' different built-in patterns.
  6. '
  7. ' author jan bodnar
  8. ' last modified May 2009
  9. ' website www.zetcode.com
  10. Imports System.Windows.Forms
  11. Imports System.Drawing
  12. Imports System.Drawing.Drawing2D
  13. Public Class WinVBApp
  14. Inherits Form
  15. Public Sub New
  16. Me.Text = "Hatches"
  17. Me.Size = New Size(360, 300)
  18. AddHandler Me.Paint AddressOf Me.OnPaint
  19. Me.CenterToScreen
  20. End Sub
  21. Private Sub OnPaint(ByVal sender As Object, ByVal e As PaintEventArgs)
  22. Dim g As Graphics = e.Graphics
  23. Dim hb As HatchBrush = New HatchBrush(HatchStyle.Cross, Color.Black, Me.BackColor)
  24. g.FillRectangle(hb, 10, 15, 90, 60)
  25. hb = New HatchBrush(HatchStyle.Percent05, Color.Black, Me.BackColor)
  26. g.FillRectangle(hb, 130, 15, 90, 60)
  27. hb = New HatchBrush(HatchStyle.SolidDiamond, Color.Black, Me.BackColor)
  28. g.FillRectangle(hb, 250, 15, 90, 60)
  29. hb = New HatchBrush(HatchStyle.DiagonalBrick, Color.Black, Me.BackColor)
  30. g.FillRectangle(hb, 10, 105, 90, 60)
  31. hb = New HatchBrush(HatchStyle.Divot, Color.Black, Me.BackColor)
  32. g.FillRectangle(hb, 130, 105, 90, 60)
  33. hb = New HatchBrush(HatchStyle.Wave, Color.Black, Me.BackColor)
  34. g.FillRectangle(hb, 250, 105, 90, 60)
  35. hb = New HatchBrush(HatchStyle.ZigZag, Color.Black, Me.BackColor)
  36. g.FillRectangle(hb, 10, 195, 90, 60)
  37. hb = New HatchBrush(HatchStyle.Sphere, Color.Black, Me.BackColor)
  38. g.FillRectangle(hb, 130, 195, 90, 60)
  39. hb = New HatchBrush(HatchStyle.Shingle, Color.Black, Me.BackColor)
  40. g.FillRectangle(hb, 250, 195, 90, 60)
  41. g.Dispose
  42. hb.Dispose
  43. End Sub
  44. Public Shared Sub Main
  45. Application.Run(New WinVBApp)
  46. End Sub
  47. End Class

这次,我们用九种不同的图案(称为剖面线)填充了九个矩形。

  1. Dim hb As HatchBrush = New HatchBrush(HatchStyle.Cross, Color.Black, Me.BackColor)

在这里,我们创建一个HatchBrush对象。 参数是图案填充样式以及前景色和背景色。 背景颜色设置为表单的颜色,因此看起来就像我们在表单上绘制的一样。

  1. g.FillRectangle(hb, 10, 15, 90, 60)

我们使用指定的阴影刷填充矩形。

绘图 - 图1

图:通口

基本形状

下面的示例在窗体控件上绘制一些基本形状。

  1. ' ZetCode Mono Visual Basic Winforms tutorial
  2. '
  3. ' This program draws basic shapes available
  4. ' in Winforms
  5. '
  6. ' author jan bodnar
  7. ' last modified May 2009
  8. ' website www.zetcode.com
  9. Imports System.Windows.Forms
  10. Imports System.Drawing
  11. Imports System.Drawing.Drawing2D
  12. Imports System.Collections.Generic
  13. Public Class WinVBApp
  14. Inherits Form
  15. Public Sub New
  16. Me.Text = "Basic Shapes"
  17. Me.Size = New Size(420, 280)
  18. AddHandler Me.Paint AddressOf Me.OnPaint
  19. Me.CenterToScreen
  20. End Sub
  21. Private Sub OnPaint(ByVal sender As Object, ByVal e As PaintEventArgs)
  22. Dim g As Graphics = e.Graphics
  23. g.SmoothingMode = SmoothingMode.AntiAlias
  24. g.FillRectangle(Brushes.Gray, 20, 20, 120, 80)
  25. g.FillRectangle(Brushes.Gray, 180, 20, 80, 80)
  26. g.FillEllipse(Brushes.Gray, 30, 120, 100, 100)
  27. g.FillEllipse(Brushes.Gray, 160, 130, 100, 70)
  28. Dim points(5) As Point
  29. points(0) = New Point(300, 40)
  30. points(1) = New Point(340, 15)
  31. points(2) = New Point(380, 40)
  32. points(3) = New Point(380, 80)
  33. points(4) = New Point(340, 105)
  34. points(5) = New Point(300, 80)
  35. g.FillPolygon(Brushes.Gray, points)
  36. g.FillPie(Brushes.Gray, New Rectangle(290, 130, 90, 90), 0, 315)
  37. g.Dispose
  38. End Sub
  39. Public Shared Sub Main
  40. Application.Run(New WinVBApp)
  41. End Sub
  42. End Class

该代码示例在表单上绘制六个形状。 矩形,正方形,圆形,椭圆形,多边形和扇形。

  1. g.SmoothingMode = SmoothingMode.AntiAlias

这使绘图更平滑。

  1. g.FillRectangle(Brushes.Gray, 20, 20, 120, 80)

这条线用灰色填充矩形。 参数是画笔颜色,矩形左上角的 x,y 坐标以及矩形的宽度和高度。

  1. Dim points(5) As Point
  2. points(0) = New Point(300, 40)
  3. points(1) = New Point(340, 15)
  4. ...

我们创建五个点的数组。

  1. g.FillPolygon(Brushes.Gray, points)

这条线绘制了一个包含六个单点的多边形。

  1. g.FillPie(Brushes.Gray, New Rectangle(290, 130, 90, 90), 0, 315)

这条线画了一个馅饼。 最后两个参数是起始角度和后掠角度。 以度为单位。

绘图 - 图2

图:基本形状

透明矩形

透明性是指能够透视材料的质量。 了解透明度的最简单方法是想象一块玻璃或水。 从技术上讲,光线可以穿过玻璃,这样我们就可以看到玻璃后面的物体。

在计算机图形学中,我们可以使用 alpha 合成来实现透明效果。 Alpha 合成是将图像与背景组合以创建部分透明外观的过程。 合成过程使用 Alpha 通道。 (wikipedia.org,answers.com)

  1. ' ZetCode Mono Visual Basic Winforms tutorial
  2. '
  3. ' This program draws ten
  4. ' rectangles with different
  5. ' levels of transparency
  6. '
  7. ' author jan bodnar
  8. ' last modified May 2009
  9. ' website www.zetcode.com
  10. Imports System.Windows.Forms
  11. Imports System.Drawing
  12. Imports System.Drawing.Drawing2D
  13. Imports System.Collections.Generic
  14. Public Class WinVBApp
  15. Inherits Form
  16. Public Sub New
  17. Me.Text = "Transparent rectangles"
  18. Me.Size = New Size(590, 110)
  19. AddHandler Me.Paint AddressOf Me.OnPaint
  20. Me.CenterToScreen
  21. End Sub
  22. Private Sub OnPaint(ByVal sender As Object, ByVal e As PaintEventArgs)
  23. Dim g As Graphics = e.Graphics
  24. For i As Integer = 1 to 10
  25. Dim color As Color = Color.FromArgb(i*25, 0, 0, 255)
  26. Dim brush As Brush = New SolidBrush(color)
  27. g.FillRectangle(brush, 50*i, 20, 40, 40)
  28. Next
  29. g.Dispose
  30. End Sub
  31. Public Shared Sub Main
  32. Application.Run(New WinVBApp)
  33. End Sub
  34. End Class

在示例中,我们将绘制十个具有不同透明度级别的矩形。

  1. Dim color As Color = Color.FromArgb(i*25, 0, 0, 255)

该行创建一个颜色对象。 第一个值是 Alpha 透明度。

  1. Dim brush As Brush = New SolidBrush(color)

我们用颜色创建画笔。

  1. g.FillRectangle(brush, 50*i, 20, 40, 40)

我们用颜色填充矩形。

绘图 - 图3

图:透明矩形

灰度图像

下面的示例创建一个灰度图像。

  1. ' ZetCode Mono Visual Basic Winforms tutorial
  2. '
  3. ' This program draws creates a grayscale
  4. ' clone of a bitmap image
  5. '
  6. ' author jan bodnar
  7. ' last modified May 2009
  8. ' website www.zetcode.com
  9. Imports System.Windows.Forms
  10. Imports System.Drawing
  11. Imports System.Drawing.Drawing2D
  12. Public Class WinVBApp
  13. Inherits Form
  14. Private rotunda As Bitmap
  15. Private gs As Bitmap
  16. Public Sub New
  17. Me.Text = "Grayscale"
  18. Me.Size = New Size(290, 150)
  19. rotunda = Me.LoadImage
  20. gs = GrayScale(rotunda.Clone)
  21. AddHandler Me.Paint AddressOf Me.OnPaint
  22. Me.CenterToScreen
  23. End Sub
  24. Private Function LoadImage As Bitmap
  25. Try
  26. rotunda = New Bitmap("rotunda.jpg")
  27. Return rotunda
  28. Catch
  29. Console.WriteLine("Image not found")
  30. Environment.Exit(1)
  31. End Try
  32. End Function
  33. Private Function GrayScale(ByVal image As Bitmap) As Bitmap
  34. Dim w As Integer = image.Width
  35. Dim h As Integer = image.Height
  36. For i as Integer = 0 To w-1
  37. For j As Integer = 0 To h-1
  38. Dim c As Color = image.GetPixel(i, j)
  39. Dim lum As Double = 0.299*c.R + 0.587*c.G + 0.114*c.B
  40. image.SetPixel(i, j, Color.FromArgb(lum, lum, lum))
  41. Next
  42. Next
  43. Return image
  44. End Function
  45. Private Sub OnPaint(ByVal sender As Object, ByVal e As PaintEventArgs)
  46. Dim g As Graphics = e.Graphics
  47. Dim r1 As New Rectangle(15, 15, rotunda.Width, rotunda.Height)
  48. g.DrawImage(rotunda, r1)
  49. Dim r2 As New Rectangle(150, 15, gs.Width, gs.Height)
  50. g.DrawImage(gs, r2)
  51. g.Dispose
  52. End Sub
  53. Public Shared Sub Main
  54. Application.Run(New WinVBApp)
  55. End Sub
  56. End Class

我们的示例中有两个图像。 一种颜色和一种灰度。

  1. rotunda = Me.LoadImage

LoadImage方法从磁盘的当前工作目录加载位图。

  1. gs = GrayScale(rotunda.Clone)

GrayScale方法从彩色图像制作灰度图像。 我们将圆形大厅图像的副本作为此方法的参数。

  1. Dim c As Color = image.GetPixel(i, j)

我们得到一个像素的颜色。

  1. Dim lum As Double = 0.299*c.R + 0.587*c.G + 0.114*c.B

该方程式计算灰度图像的亮度。 如果我们使用这些因素来缩放颜色的红色,绿色和蓝色部分,则人眼会将图像视为灰色。

  1. image.SetPixel(i, j, Color.FromArgb(lum, lum, lum))

我们修改像素。

绘图 - 图4

图:灰度图像

绘制文字

要在 Winforms Form上绘制文本,我们使用DrawString方法。

  1. ' ZetCode Mono Visual Basic Winforms tutorial
  2. '
  3. ' This program draws lyrics of
  4. ' a song
  5. '
  6. ' author jan bodnar
  7. ' last modified May 2009
  8. ' website www.zetcode.com
  9. Imports System.Windows.Forms
  10. Imports System.Drawing
  11. Imports System.Drawing.Drawing2D
  12. Imports System.Collections.Generic
  13. Public Class WinVBApp
  14. Inherits Form
  15. Public Sub New
  16. Me.Text = "You know I'm no Good"
  17. Me.Size = New Size(380, 450)
  18. AddHandler Me.Paint AddressOf Me.OnPaint
  19. Me.CenterToScreen
  20. End Sub
  21. Private Sub OnPaint(ByVal sender As Object, ByVal e As PaintEventArgs)
  22. Dim g As Graphics = e.Graphics
  23. Dim ft As New Font("Purisa", 10)
  24. Dim br As New SolidBrush(Color.Black)
  25. Dim pt As PointF = New PointF(20.0f, 20.0f)
  26. g.DrawString("Meet you downstairs in the bar and heard", ft, br, pt)
  27. pt = New PointF(20.0f, 50.0f)
  28. g.DrawString("Your rolled up sleeves and your skull t-shirt", ft, br, pt)
  29. pt = New PointF(20.0f, 80.0f)
  30. g.DrawString("You say why did you do it with him today?", ft, br, pt)
  31. pt = New PointF(20.0f, 110.0f)
  32. g.DrawString("And sniffed me out like I was tanqueray", ft, br, pt)
  33. pt = New PointF(20.0f, 160.0f)
  34. g.DrawString("Cause you’re my fella, my guy", ft, br, pt)
  35. pt = New PointF(20.0f, 190.0f)
  36. g.DrawString("Hand me your stella and fly", ft, br, pt)
  37. pt = New PointF(20.0f, 220.0f)
  38. g.DrawString("By the time I’m out the door", ft, br, pt)
  39. pt = New PointF(20.0f, 250.0f)
  40. g.DrawString("You tear me down like roger moore", ft, br, pt)
  41. pt = New PointF(20.0f, 300.0f)
  42. g.DrawString("I cheated myself", ft, br, pt)
  43. pt = New PointF(20.0f, 330.0f)
  44. g.DrawString("Like I knew I would", ft, br, pt)
  45. pt = New PointF(20.0f, 360.0f)
  46. g.DrawString("I told ya, I was trouble", ft, br, pt)
  47. pt = New PointF(20.0f, 390.0f)
  48. g.DrawString("You know that I’m no good", ft, br, pt)
  49. ft.Dispose
  50. br.Dispose
  51. g.Dispose
  52. End Sub
  53. Public Shared Sub Main
  54. Application.Run(New WinVBApp)
  55. End Sub
  56. End Class

在我们的示例中,我们在 Winforms 窗体上绘制歌曲的歌词。

  1. Dim ft As New Font("Purisa", 10)

我们使用 10 磅高的 Purisa 字体。

  1. Dim pt As PointF = New PointF(20.0f, 20.0f)

要在表单上绘制字符串,我们必须使用浮点值。

  1. g.DrawString("Meet you downstairs in the bar and heard", ft, br, pt)

DrawString方法采用以下参数:要绘制的文本,字体,笔刷和PointF对象。

绘图 - 图5

图:歌词

等待

在此示例中,我们使用透明效果创建一个等待演示。 我们将绘制 8 条线,这些线将逐渐消失,从而产生一种错觉,即一条线在移动。 这种效果通常用于通知用户,一项艰巨的任务正在幕后进行。 一个示例是通过互联网流式传输视频。

  1. ' ZetCode Mono Visual Basic Winforms tutorial
  2. '
  3. ' This program creates a waiting
  4. ' demo
  5. '
  6. ' author jan bodnar
  7. ' last modified May 2009
  8. ' website www.zetcode.com
  9. Imports System.Windows.Forms
  10. Imports System.Drawing
  11. Imports System.Drawing.Drawing2D
  12. Imports System.Collections.Generic
  13. Public Class WinVBApp
  14. Inherits Form
  15. Dim trs(,) As Integer = New Integer(,) { _
  16. { 0, 35, 70, 100, 150, 180, 210, 250 }, _
  17. { 250, 0, 35, 70, 100, 150, 180, 210 }, _
  18. { 210, 250, 0, 35, 70, 100, 150, 180 }, _
  19. { 180, 210, 250, 0, 35, 70, 100, 150 }, _
  20. { 150, 180, 210, 250, 0, 35, 70, 100 }, _
  21. { 100, 150, 180, 210, 250, 0, 35, 70 }, _
  22. { 70, 100, 150, 180, 210, 250, 0, 35 }, _
  23. { 35, 70, 100, 150, 180, 210, 250, 0 } _
  24. }
  25. Dim count As Integer = 0
  26. Dim timer As Timer
  27. Public Sub New
  28. Me.Text = "Waiting"
  29. Me.Size = New Size(250, 150)
  30. timer = New Timer
  31. timer.Enabled = True
  32. timer.Interval = 80
  33. AddHandler timer.Tick, AddressOf Me.OnTick
  34. AddHandler Me.Paint, AddressOf Me.OnPaint
  35. Me.CenterToScreen
  36. End Sub
  37. Private Sub OnTick(ByVal sender As Object, ByVal e As EventArgs)
  38. count = count + 1
  39. Me.Refresh
  40. End Sub
  41. Private Sub OnPaint(ByVal sender As Object, ByVal e As PaintEventArgs)
  42. Dim g As Graphics = e.Graphics
  43. g.SmoothingMode = SmoothingMode.AntiAlias
  44. Dim si As Size = Me.ClientSize
  45. g.TranslateTransform(si.Width/2, si.Height/2)
  46. For i As Integer = 0 To 7
  47. Dim color As Color = Color.FromArgb(trs(count Mod 8, i), 30, 30, 30)
  48. Dim pen As New Pen(color, 3)
  49. pen.StartCap = LineCap.Round
  50. pen.EndCap = LineCap.Round
  51. g.DrawLine(pen, 0, -10, 0, -40)
  52. g.RotateTransform(45)
  53. pen.Dispose
  54. Next
  55. g.Dispose
  56. End Sub
  57. Public Shared Sub Main
  58. Application.Run(New WinVBApp)
  59. End Sub
  60. End Class

我们用八个不同的 alpha 值绘制八条线。

  1. timer = New Timer
  2. timer.Enabled = True
  3. timer.Interval = 80
  4. AddHandler timer.Tick, AddressOf Me.OnTick

我们使用Timer制作动画。

  1. Dim trs(,) As Integer = New Integer(,) { _
  2. { 0, 35, 70, 100, 150, 180, 210, 250 }, _
  3. ...
  4. }

这是此演示中使用的透明度值的二维集合。 有 8 行,每行一种状态。 8 行中的每行将连续使用这些值。

  1. Dim pen As New Pen(color, 3)
  2. pen.StartCap = LineCap.Round
  3. pen.EndCap = LineCap.Round

我们使线条更粗一些,以便更好地显示它们。 我们用带帽的线画线。

  1. Dim color As Color = Color.FromArgb(trs(count Mod 8, i), 30, 30, 30)

在这里,我们定义了一条线的透明度值。

  1. g.DrawLine(pen, 0, -10, 0, -40)
  2. g.RotateTransform(45)

我们画了 8 条线。 它们是顺时针旋转的。

绘图 - 图6

图:等待

在本章中,我们使用 Visual Basic 在 Winforms 中进行了一些绘图。