上篇《用C#制作含万年历的台历(2009年样张)之1》(http://blog.csdn.net/johnsuna/archive/2009/01/02/3683939.aspx)给出了台历的各种实样图,从这篇开始我将用程序写出各个台历样式的实现。
本篇说说大致的框架,好象建房子一样,先搭框架,框架答好之后,将砖等再填充进去。
首先,建一个基础的接口类。由于所有的台历均需要实现“画”的动作,所以,我这里建立一个“画”的接口类。
为了与我之前的保持统一,这里就叫:IImageEffectDrawer类了。
它非常的简单:
using System.Drawing;
namespace BrawDraw.ImageEffects
{
/// <summary>
/// 图片特效绘画器
/// </summary>
public interface IImageEffectDrawer
{
/// <summary>
/// 绘画图片特效
/// </summary>
/// <returns>已经画好的图片</returns>
Image Draw();
}
}
另外,我们可能需要设置一个默认的类,需要在不做参数设置或不设定的情况下可以使用:
using System.Drawing;
using System.Drawing.Drawing2D;
namespace BrawDraw.ImageEffects
{
/// <summary>
/// 默认的绘画器
/// </summary>
public class DefaultImageEffectDrawer : IImageEffectDrawer
{
/// <summary>
/// 将画出默认的图片
/// </summary>
/// <returns>已经画好的图片</returns>
Image IImageEffectDrawer.Draw()
{
Image image = new Bitmap(640, 480);
using (Graphics graphics = Graphics.FromImage(image))
{
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.DrawString("默认图片", new Font("黑体", 120f), new SolidBrush(Color.Red), 0, 0);
}
return image;
}
}
}
接着,后面的所有台历、月历甚至年历,均可以继承自IImageEffectDrawer类,然后在这些类里实现:
public Image Draw()
{
Image img = new Image(calendarWidth, calendarHeight);
//这里是绘制代码
return img;
}
调用时,使用myCalendar.Draw()即可。当然,很多时候,可能还需要对该图片进行保存,比如保存为jpg, png等格式图片。那么,可以在IImageEffectDrawer接口里加入string PhotoSave();这样的方法。
下例是一个框架:
using System;
using System.Collections;
using System.ComponentModel;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using BrawDraw.ImageEffects;
namespace BrawDraw.Com.PhotoFrame.Net.ChineseCalendar.Calendar
{
public class MCInnerLeftRight : System.Windows.Forms.Control, IImageEffectDrawer
{
private SolidBrush brush1 = new SolidBrush(Color.FromArgb(0, 0, 0, 0));
private SolidBrush brush4 = new SolidBrush(Color.Red);
private Pen stroke1 = new Pen(Color.Black, 1F);
private Pen stroke3 = new Pen(Color.Red, 1F);
private Font font6 = new Font("EU-F2", 18F, ((FontStyle)(0)), GraphicsUnit.Point, 1);
private Font font7 = new Font("微软雅黑", 7.5F, ((FontStyle)(0)), GraphicsUnit.Point, 1);
private Font font9 = new Font("微软雅黑", 5.25F, ((FontStyle)(0)), GraphicsUnit.Point, 1);
private StringFormat stringformat1 = new StringFormat(StringFormat.GenericTypographic);
private RectangleF Image1Rectangle = new RectangleF(-2, 807, 1015, 700);
protected Bitmap Image1;
protected Rectangle Rect9 = new Rectangle(393, 0, 606, 678);
protected Rectangle Rect1 = new Rectangle(0, 0, 393, 678);
protected string Text3 = "2";
private System.Single Text3PointX = 802;
private System.Single Text3PointY = 370;
private Font Text3Font = new Font("Arial Black", 219.75F, ((FontStyle)(0)), GraphicsUnit.Point, 1);
private SolidBrush Text3Brush = new SolidBrush(Color.Silver);
protected Rectangle Rect2 = new Rectangle(411, 73, 574, 504);
protected Rectangle Rect3 = new Rectangle(411, 89, 81, 96);
protected Rectangle Rect4 = new Rectangle(411, 582, 116, 88);
protected Rectangle Rect5 = new Rectangle(550, 582, 116, 88);
private Pen Rect6Pen = new Pen(Color.IndianRed, 1F);
protected Rectangle Rect6 = new Rectangle(999, 0, 16, 678);
protected Rectangle Rect7 = new Rectangle(22, 19, 18, 18);
protected Rectangle Rect8 = new Rectangle(969, 19, 18, 18);
protected string Text6 = "二月 February";
private System.Single Text6PointX = 767;
private System.Single Text6PointY = 590;
private Font Text6Font = new Font("方正大黑简体", 24F, ((FontStyle)(0)), GraphicsUnit.Point, 1);
private SolidBrush Text6Brush = new SolidBrush(Color.Teal);
protected string Text8 = "SUN星期日";
private System.Single Text8PointX = 414;
private System.Single Text8PointY = 71;
private Font Text8Font = new Font("微软雅黑", 10.5F, ((FontStyle)(0)), GraphicsUnit.Point, 134);
protected string Text9 = "1";
private System.Single Text9PointX = 913;
private System.Single Text9PointY = 84;
private Font Text9Font = new Font("EU-F2", 18F, ((FontStyle)(0)), GraphicsUnit.Point, 134);
protected string Text10 = "闰五月";
private System.Single Text10PointX = 950;
private System.Single Text10PointY = 168;
private Font Text10Font = new Font("微软雅黑", 7.5F, ((FontStyle)(0)), GraphicsUnit.Point, 134);
protected string Text11 = "23";
private System.Single Text11PointX = 422;
private System.Single Text11PointY = 476;
protected string Text12 = "廿三";
private System.Single Text12PointX = 468;
private System.Single Text12PointY = 539;
protected string Text13 = "30";
private System.Single Text13PointX = 422;
private System.Single Text13PointY = 495;
protected string Text14 = "初一";
private System.Single Text14PointX = 468;
private System.Single Text14PointY = 558;
protected string Text15 = "18";
private System.Single Text15PointX = 513;
private System.Single Text15PointY = 631;
protected string Text16 = "17";
private System.Single Text16PointX = 497;
private System.Single Text16PointY = 631;
protected string Text17 = "一月 January";
private System.Single Text17PointX = 414;
private System.Single Text17PointY = 583;
private Font Text17Font = new Font("微软雅黑", 9F, ((FontStyle)(0)), GraphicsUnit.Point, 134);
protected PointF Line1PointStart = new PointF(555F, 667F);
protected PointF Line1PointEnd = new PointF(562F, 661F);
protected PointF Line2PointStart = new PointF(571F, 667F);
protected PointF Line2PointEnd = new PointF(578F, 661F);
protected string Text20 = "24";
private System.Single Text20PointX = 568;
private System.Single Text20PointY = 656;
protected string Text21 = "31";
private System.Single Text21PointX = 574;
private System.Single Text21PointY = 662;
protected string Text18 = "23";
private System.Single Text18PointX = 552;
private System.Single Text18PointY = 656;
private Font Text18Font = new Font("微软雅黑", 5.25F, ((FontStyle)(0)), GraphicsUnit.Point, 134);
protected string Text19 = "30";
private System.Single Text19PointX = 558;
private System.Single Text19PointY = 662;
protected Rectangle Rect10 = new Rectangle(904, 89, 81, 96);
protected string Text22 = "2009";
private System.Single Text22PointX = 911;
private System.Single Text22PointY = 629;
private Font Text22Font = new Font("方正大黑简体", 21.75F, ((FontStyle)(0)), GraphicsUnit.Point, 134);
int _calendarWidth = 688;
int _calendarHeight = 1066;
/// <summary>
/// 获取或设置月历宽度
/// </summary>
[Category("Calendar"), DefaultValue(688), Description("月历宽度")]
public int CalendarWidth
{
get
{
return _calendarWidth;
}
set
{
_calendarWidth = value;
this.Invalidate();
}
}
[Category("Calendar"), DefaultValue(1066), Description("月历高度")]
public int CalendarHeight
{
get
{
return _calendarHeight;
}
set
{
_calendarHeight = value;
this.Invalidate();
}
}
public MCInnerLeftRight()
{
this.InitializeGraphics();
}
private void InitializeGraphics()
{
this.stringformat1.Alignment = StringAlignment.Near;
this.Image1 = this.ImageFromEmbedded("MyNameSpace.20090101324.jpg");
}
public virtual void RenderTheGraphics(Graphics g)
{
g.SmoothingMode = SmoothingMode.AntiAlias;
g.TextRenderingHint = TextRenderingHint.AntiAlias;
g.DrawImage(this.Image1, this.Image1Rectangle);
g.FillRectangle(this.brush1, this.Rect9);
g.DrawRectangle(this.stroke1, this.Rect9);
g.FillRectangle(this.brush1, this.Rect1);
g.DrawRectangle(this.stroke1, this.Rect1);
g.DrawString(this.Text3, this.Text3Font, this.Text3Brush, this.Text3PointX, this.Text3PointY);
g.FillRectangle(this.brush1, this.Rect2);
g.DrawRectangle(this.stroke1, this.Rect2);
g.FillRectangle(this.brush1, this.Rect3);
g.DrawRectangle(this.stroke1, this.Rect3);
g.FillRectangle(this.brush1, this.Rect4);
g.DrawRectangle(this.stroke1, this.Rect4);
g.FillRectangle(this.brush1, this.Rect5);
g.DrawRectangle(this.stroke1, this.Rect5);
g.FillRectangle(this.brush1, this.Rect6);
g.DrawRectangle(this.Rect6Pen, this.Rect6);
g.FillRectangle(this.brush1, this.Rect7);
g.DrawRectangle(this.stroke3, this.Rect7);
g.FillRectangle(this.brush1, this.Rect8);
g.DrawRectangle(this.stroke3, this.Rect8);
g.DrawString(this.Text6, this.Text6Font, this.Text6Brush, this.Text6PointX, this.Text6PointY);
g.DrawString(this.Text8, this.Text8Font, this.brush4, this.Text8PointX, this.Text8PointY);
g.DrawString(this.Text9, this.Text9Font, this.brush4, this.Text9PointX, this.Text9PointY);
g.DrawString(this.Text10, this.Text10Font, this.brush4, this.Text10PointX, this.Text10PointY);
g.DrawString(this.Text11, this.font6, this.brush4, this.Text11PointX, this.Text11PointY);
g.DrawString(this.Text12, this.font7, this.brush4, this.Text12PointX, this.Text12PointY);
g.DrawString(this.Text13, this.font6, this.brush4, this.Text13PointX, this.Text13PointY);
g.DrawString(this.Text14, this.font7, this.brush4, this.Text14PointX, this.Text14PointY);
g.DrawString(this.Text15, this.font7, this.brush4, this.Text15PointX, this.Text15PointY);
g.DrawString(this.Text16, this.font7, this.brush4, this.Text16PointX, this.Text16PointY);
g.DrawString(this.Text17, this.Text17Font, this.brush4, this.Text17PointX, this.Text17PointY);
g.DrawLine(this.stroke1, this.Line1PointStart, this.Line1PointEnd);
g.DrawLine(this.stroke1, this.Line2PointStart, this.Line2PointEnd);
g.DrawString(this.Text20, this.font9, this.brush4, this.Text20PointX, this.Text20PointY);
g.DrawString(this.Text21, this.font9, this.brush4, this.Text21PointX, this.Text21PointY);
g.DrawString(this.Text18, this.Text18Font, this.brush4, this.Text18PointX, this.Text18PointY);
g.DrawString(this.Text19, this.font9, this.brush4, this.Text19PointX, this.Text19PointY);
g.FillRectangle(this.brush1, this.Rect10);
g.DrawRectangle(this.stroke1, this.Rect10);
g.DrawString(this.Text22, this.Text22Font, this.brush4, this.Text22PointX, this.Text22PointY);
}
private void DisposeGraphics()
{
this.brush1.Dispose();
this.brush4.Dispose();
this.stroke1.Dispose();
this.stroke3.Dispose();
this.font6.Dispose();
this.font7.Dispose();
this.font9.Dispose();
this.stringformat1.Dispose();
this.Image1.Dispose();
this.Text3Font.Dispose();
this.Text3Brush.Dispose();
this.Rect6Pen.Dispose();
this.Text6Font.Dispose();
this.Text6Brush.Dispose();
this.Text8Font.Dispose();
this.Text9Font.Dispose();
this.Text10Font.Dispose();
this.Text17Font.Dispose();
this.Text18Font.Dispose();
this.Text22Font.Dispose();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
this.DisposeGraphics();
}
}
private Bitmap ImageFromEmbedded(string embeddedPath)
{
System.IO.Stream imageStream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(embeddedPath);
Bitmap img = new Bitmap(imageStream);
return img;
}
public void DrawCalendar(Graphics gg)
{
//总体设置
gg.InterpolationMode = InterpolationMode.HighQualityBicubic;
gg.SmoothingMode = SmoothingMode.HighQuality;
gg.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
// 这里是你的代码,将用到RenderTheGraphics(Graphics g),即调用:RenderTheGraphics(gg);以及其他处理等。
gg.Dispose();
}
#region IImageEffectDrawer 成员
public Image Draw()
{
Bitmap bmp = new Bitmap(this.CalendarWidth, this.CalendarHeight);
Graphics g = Graphics.FromImage(bmp);
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
g.PageUnit = GraphicsUnit.Pixel;
this.DrawCalendar(g);
g.Dispose();
return bmp;
}
#endregion
}
}
它实现类似这样的效果:
图1 台历的基本框架样式
上图仅是下图所示台历的基本框架而已,它标示了各个部件的关健位置及少数应注意的细节。这样做的目的是分成多个模块,然后一个模块一个模块地套进去,最终实现全部程序的制作。
图2 台历实样
注:上面代码还有诸多不完善的地方,因此需要今后不断的“加砖加瓦”。