原文: http://zetcode.com/tutorials/ironpythontutorial/paintingII/

在 IronPython Mono Winforms 教程的这一部分中,我们将继续绘图。

甜甜圈

在下面的示例中,我们通过旋转一堆椭圆来创建复杂的形状。

donut.py

  1. #!/usr/bin/ipy
  2. import clr
  3. clr.AddReference("System.Windows.Forms")
  4. clr.AddReference("System.Drawing")
  5. from System.Windows.Forms import Application, Form
  6. from System.Drawing import Size, Color, SolidBrush, Pen
  7. class IForm(Form):
  8. def __init__(self):
  9. self.Text = 'Donut'
  10. self.Size = Size(350, 300)
  11. self.Paint += self.OnPaint
  12. self.CenterToScreen()
  13. def OnPaint(self, event):
  14. g = event.Graphics
  15. pen = Pen(Color.Gray, 1)
  16. size = self.ClientSize
  17. g.TranslateTransform(size.Width/2, size.Height/2)
  18. g.DrawEllipse(pen, -125, -125, 250, 250)
  19. for i in range(0, 36):
  20. g.DrawEllipse(pen, 0, 0, 120, 50)
  21. g.RotateTransform(10)
  22. g.Dispose()
  23. Application.Run(IForm())

我们在表格上画了五行。 每行具有不同的DashStyle

  1. size = self.ClientSize
  2. g.TranslateTransform(size.Width/2, size.Height/2)
  3. g.DrawEllipse(pen, -125, -125, 250, 250)

我们在表格中间画一个圆。

  1. for i in range(0, 36):
  2. g.DrawEllipse(pen, 0, 0, 120, 50)
  3. g.RotateTransform(10)

我们绘制 36 个椭圆,每个椭圆在最后一个椭圆之后旋转 10 度。 从而得到甜甜圈的对象。

IronPython Mono Winforms 中的绘图 II - 图1

图:多纳圈

透明矩形

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

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

transparentrectangles.py

  1. #!/usr/bin/ipy
  2. import clr
  3. clr.AddReference("System.Windows.Forms")
  4. clr.AddReference("System.Drawing")
  5. from System.Windows.Forms import Application, Form
  6. from System.Drawing import Size, Color, SolidBrush
  7. class IForm(Form):
  8. def __init__(self):
  9. self.Text = 'Transparent rectangles'
  10. self.Size = Size(590, 110)
  11. self.Paint += self.OnPaint
  12. self.CenterToScreen()
  13. def OnPaint(self, event):
  14. g = event.Graphics
  15. for i in range(1, 11):
  16. color = Color.FromArgb(i*25, 0, 0, 255)
  17. brush = SolidBrush(color)
  18. g.FillRectangle(brush, 50*i, 20, 40, 40)
  19. Application.Run(IForm())

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

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

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

  1. brush = SolidBrush(color)

我们用颜色创建画笔。

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

我们画一个矩形。

IronPython Mono Winforms 中的绘图 II - 图2

图:透明矩形

灰度图像

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

grayscale.py

  1. #!/usr/bin/ipy
  2. import clr
  3. import sys
  4. clr.AddReference("System.Windows.Forms")
  5. clr.AddReference("System.Drawing")
  6. from System.Windows.Forms import Application, Form
  7. from System.Drawing import Size, Rectangle
  8. from System.Drawing import Bitmap, Color
  9. class IForm(Form):
  10. def __init__(self):
  11. self.Text = 'Grayscale'
  12. self.Size = Size(290, 150)
  13. self.Paint += self.OnPaint
  14. self.rotunda = self.loadImage()
  15. self.gs = self.grayScale(self.rotunda.Clone())
  16. self.CenterToScreen()
  17. def loadImage(self):
  18. try:
  19. rotunda = Bitmap("rotunda.jpg")
  20. return rotunda
  21. except Exception, e:
  22. print e.msg
  23. sys.exit(1)
  24. def grayScale(self, image):
  25. w = image.Width
  26. h = image.Height
  27. for i in range(w):
  28. for j in range(h):
  29. c = image.GetPixel(i, j)
  30. lum = 0.299*c.R + 0.587*c.G + 0.114*c.B
  31. image.SetPixel(i, j, Color.FromArgb(lum, lum, lum))
  32. return image
  33. def OnPaint(self, event):
  34. g = event.Graphics
  35. r1 = Rectangle(15, 15, self.rotunda.Width, self.rotunda.Height)
  36. g.DrawImage(self.rotunda, r1)
  37. r2 = Rectangle(150, 15, self.gs.Width, self.gs.Height)
  38. g.DrawImage(self.gs, r2)
  39. g.Dispose()
  40. Application.Run(IForm())

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

  1. self.rotunda = self.loadImage()

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

  1. self.gs = self.grayScale(self.rotunda.Clone())

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

  1. c = image.GetPixel(i, j)

我们从图像中获得所有像素。

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

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

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

我们修改像素。

渐变

在计算机图形学中,渐变是从浅到深或从一种颜色到另一种颜色的阴影的平滑混合。 在 2D 绘图程序和绘图程序中,渐变用于创建彩色背景和特殊效果以及模拟灯光和阴影。 (answers.com)

gradients.py

  1. #!/usr/bin/ipy
  2. import clr
  3. clr.AddReference("System.Windows.Forms")
  4. clr.AddReference("System.Drawing")
  5. from System.Windows.Forms import Application, Form
  6. from System.Drawing import Size, Color, Point
  7. from System.Drawing.Drawing2D import LinearGradientBrush
  8. class IForm(Form):
  9. def __init__(self):
  10. self.Text = 'Gradients'
  11. self.Size = Size(350, 350)
  12. self.Paint += self.OnPaint
  13. self.CenterToScreen()
  14. def OnPaint(self, event):
  15. g = event.Graphics
  16. pt1 = Point(5, 5)
  17. pt2 = Point(25, 25)
  18. lg = LinearGradientBrush(pt1, pt2, Color.Red, Color.Black)
  19. g.FillRectangle(lg, 20, 20, 300, 40)
  20. pt1 = Point(5, 25)
  21. pt2 = Point(20, 2)
  22. lg = LinearGradientBrush(pt1, pt2, Color.Yellow, Color.Black)
  23. g.FillRectangle(lg, 20, 80, 300, 40)
  24. pt1 = Point(5, 25)
  25. pt2 = Point(2, 2)
  26. lg = LinearGradientBrush(pt1, pt2, Color.Green, Color.Black)
  27. g.FillRectangle(lg, 20, 140, 300, 40)
  28. pt1 = Point(25, 25)
  29. pt2 = Point(15, 25)
  30. lg = LinearGradientBrush(pt1, pt2, Color.Blue, Color.Black)
  31. g.FillRectangle(lg, 20, 200, 300, 40)
  32. pt1 = Point(0, 10)
  33. pt2 = Point(0, 20)
  34. lg = LinearGradientBrush(pt1, pt2, Color.Orange, Color.Black)
  35. g.FillRectangle(lg, 20, 260, 300, 40)
  36. lg.Dispose()
  37. g.Dispose()
  38. Application.Run(IForm())

我们绘制五个矩形,这些矩形填充有不同的线性渐变。

  1. pt1 = Point(5, 5)
  2. pt2 = Point(25, 25)

这两个是线性渐变画笔的控制点。

  1. lg = LinearGradientBrush(pt1, pt2, Color.Red, Color.Black)

我们创建LinearGradientBrush对象。 我们使用两个控制点和两种混合颜色。

IronPython Mono Winforms 中的绘图 II - 图3

图:渐变

等待

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

waiting.py

  1. #!/usr/bin/ipy
  2. import clr
  3. clr.AddReference("System.Windows.Forms")
  4. clr.AddReference("System.Drawing")
  5. from System.Windows.Forms import Application, Form, Timer
  6. from System.Drawing import Size, Color, SolidBrush, Pen
  7. from System.Drawing.Drawing2D import SmoothingMode, LineCap
  8. from System.ComponentModel import Container
  9. trs = (
  10. ( 0, 35, 70, 100, 150, 180, 210, 250 ),
  11. ( 250, 0, 35, 70, 100, 150, 180, 210 ),
  12. ( 210, 250, 0, 35, 70, 100, 150, 180 ),
  13. ( 180, 210, 250, 0, 35, 70, 100, 150 ),
  14. ( 150, 180, 210, 250, 0, 35, 70, 100 ),
  15. ( 100, 150, 180, 210, 250, 0, 35, 70 ),
  16. ( 70, 100, 150, 180, 210, 250, 0, 35 ),
  17. ( 35, 70, 100, 150, 180, 210, 250, 0 )
  18. )
  19. class IForm(Form):
  20. def __init__(self):
  21. self.Text = 'Waiting'
  22. self.Size = Size(250, 150)
  23. self.Paint += self.OnPaint
  24. self.count = 0
  25. self.timer = Timer(Container())
  26. self.timer.Enabled = True
  27. self.timer.Interval = 80
  28. self.timer.Tick += self.OnTick
  29. self.CenterToScreen()
  30. def OnTick(self, sender, event):
  31. self.count = self.count + 1
  32. self.Refresh()
  33. def OnPaint(self, event):
  34. g = event.Graphics
  35. g.SmoothingMode = SmoothingMode.AntiAlias
  36. size = self.ClientSize
  37. g.TranslateTransform(size.Width/2, size.Height/2)
  38. for i in range(0, 8):
  39. color = Color.FromArgb(trs[self.count%8][i], 30, 30, 30)
  40. pen = Pen(color, 3)
  41. pen.StartCap = LineCap.Round
  42. pen.EndCap = LineCap.Round
  43. g.DrawLine(pen, 0, -10, 0, -40)
  44. g.RotateTransform(45)
  45. pen.Dispose()
  46. g.Dispose()
  47. Application.Run(IForm())

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

  1. self.timer = Timer(Container())
  2. self.timer.Enabled = True
  3. self.timer.Interval = 80
  4. self.timer.Tick += self.On

我们使用Timer制作动画。

  1. trs = (
  2. ( 0, 35, 70, 100, 150, 180, 210, 250 ),
  3. ...
  4. )

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

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

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

  1. color = Color.FromArgb(trs[self.count%8][i], 30, 30, 30)

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

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

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

IronPython Mono Winforms 中的绘图 II - 图4

图:等待

在 IronPython Winforms 教程的这一章中,我们在 Mono Winforms 库中做了一些更高级的绘图。