C# 画国标五星红旗
时间:2010-10-05 来源:Jeffery You
![](/bbs/images/1c53668bcee393edac0d7b3b3daff1ae.png)
2 {
3 float WidthProportion { get; }
4 float HeightProportion { get; }
5 SizeF Size { get; set; }
6
7 void AdjustFlagSizeF(int width);
8 Image GetFlagImage();
9 }
![](/bbs/images/1c53668bcee393edac0d7b3b3daff1ae.png)
2 {
3 #region - INationFlag Members -
4
5 public float WidthProportion { get { return 3F; } }
6 public float HeightProportion { get { return 2F; } }
7
8 SizeF size = SizeF.Empty;
9
10 public SizeF Size
11 {
12 get { return size; }
13 set { if (size != value) size = value; }
14 }
15
16 public void AdjustFlagSizeF(int w)
17 {
18 int width = w + w % (int)WidthProportion;
19 int height = (int)(HeightProportion * width / WidthProportion);
20
21 Size = new SizeF(width, height);
22 }
23
24 public Image GetFlagImage()
25 {
26 Bitmap flag = new Bitmap((int)size.Width, (int)size.Height);
27 float piece = size.Width / 30;
28
29 int bigStarRadius = (int)(piece * 3);
30 int smlStarRadius = (int)piece;
31
32 using (Graphics g = Graphics.FromImage(flag))
33 {
34 g.SmoothingMode = SmoothingMode.AntiAlias;
35 g.FillRectangle(Brushes.Red, 0, 0, size.Width, size.Height);
36
37 g.DrawImage(GetStarImage(bigStarRadius), piece * 2, piece * 2);
38 g.DrawImage(GetStarImage(smlStarRadius, -(int)(Math.Atan(3.0 / 5.0) * 180.0 / Math.PI) - 18), piece * 9, piece);
39 g.DrawImage(GetStarImage(smlStarRadius, -(int)(Math.Atan(1.0 / 7.0) * 180.0 / Math.PI) - 18), piece * 11, piece * 3);
40 g.DrawImage(GetStarImage(smlStarRadius, 0), piece * 11, piece * 6);
41 g.DrawImage(GetStarImage(smlStarRadius, (int)(Math.Atan(4.0 / 5.0) * 180.0 / Math.PI) - 18), piece * 9, piece * 8);
42 }
43
44 return flag;
45 }
46
47 #endregion
48
49 #region - Private Members -
50
51 public Image GetStarImage(int radius)
52 {
53 Bitmap bigStar = new Bitmap(radius * 2, radius * 2);
54
55 using (Graphics g = Graphics.FromImage(bigStar))
56 {
57 g.SmoothingMode = SmoothingMode.AntiAlias;
58 Point pc = new Point(radius, radius);
59
60 PointF p0 = new PointF(pc.X, pc.Y - radius);
61 PointF p1 = new PointF((float)(pc.X + radius * Math.Sin(72 * Math.PI / 180)), (float)(pc.Y - radius * Math.Cos(72 * Math.PI / 180)));
62 PointF p2 = new PointF((float)(pc.X + radius * Math.Sin(36 * Math.PI / 180)), (float)(pc.Y + radius * Math.Cos(36 * Math.PI / 180)));
63 PointF p3 = new PointF((float)(pc.X - radius * Math.Sin(36 * Math.PI / 180)), (float)(pc.Y + radius * Math.Cos(36 * Math.PI / 180)));
64 PointF p4 = new PointF((float)(pc.X - radius * Math.Sin(72 * Math.PI / 180)), (float)(pc.Y - radius * Math.Cos(72 * Math.PI / 180)));
65
66 using (GraphicsPath path = new GraphicsPath(FillMode.Winding))
67 {
68 path.AddLine(p0, p2);
69 path.AddLine(p2, p4);
70 path.AddLine(p4, p1);
71 path.AddLine(p1, p3);
72 path.AddLine(p3, p0);
73 path.CloseFigure();
74 g.FillPath(Brushes.Yellow, path);
75 }
76 }
77 return bigStar;
78 }
79
80 public Image GetStarImage(int radius, int angle)
81 {
82 return RotateImage(GetStarImage(radius), angle);
83 }
84 public Image RotateImage(Image b, int angle)
85 {
86 angle = angle % 360;
87 // 弧度转换
88 double radian = angle * Math.PI / 180.0;
89 double cos = Math.Cos(radian);
90 double sin = Math.Sin(radian);
91 // 原图的宽和高
92 int w = b.Width;
93 int h = b.Height;
94 int W = (int)(Math.Max(Math.Abs(w * cos - h * sin), Math.Abs(w * cos + h * sin)));
95 int H = (int)(Math.Max(Math.Abs(w * sin - h * cos), Math.Abs(w * sin + h * cos)));
96 // 目标位图
97 Bitmap dsImage = new Bitmap(W, H);
98 using (Graphics g = Graphics.FromImage(dsImage))
99 {
100 g.InterpolationMode = InterpolationMode.Bilinear;
101 g.SmoothingMode = SmoothingMode.AntiAlias;
102 // 计算偏移量
103 Point Offset = new Point((W - w) / 2, (H - h) / 2);
104 // 构造图像显示区域:让图像的中心与窗口的中心点一致
105 Rectangle rect = new Rectangle(Offset.X, Offset.Y, w, h);
106 Point center = new Point(rect.X + rect.Width / 2, rect.Y + rect.Height / 2);
107 g.TranslateTransform(center.X, center.Y);
108 g.RotateTransform(angle - 360);
109 // 恢复图像在水平和垂直方向的平移
110 g.TranslateTransform(-center.X, -center.Y);
111 g.DrawImage(b, rect);
112 // 重至绘图的所有变换
113 g.ResetTransform();
114 g.Save();
115
116 }
117 return dsImage.Clone(new Rectangle((W - w) / 2, (H - h) / 2, w, h), PixelFormat.DontCare);
118 }
119
120 #endregion
121
122 #region - Constructor -
123
124 public ChinaFlag(int w)
125 {
126 AdjustFlagSizeF(w);
127 }
128
129 #endregion
130 }
131
![](/bbs/images/1c53668bcee393edac0d7b3b3daff1ae.png)
2 {
3 public FrmMain()
4 {
5 InitializeComponent();
6 }
7 private void pbxCanvas_Paint(object sender, PaintEventArgs e)
8 {
9 INationFlag chinaFlag = new ChinaFlag(pbxCanvas.Width);
10 e.Graphics.DrawImage(chinaFlag.GetFlagImage(), 0, 0);
11 }
12 private void pbxCanvas_Resize(object sender, EventArgs e)
13 {
14 pbxCanvas.Invalidate();
15 }
16 }
本来是放在自己 QQ 博客里面的,因为《偷窥门事件》,最近不太想用 QQ 了,把一些东西陆陆续续地搬过来。
相关阅读 更多 +