C# 绘制矢量图形 [原创]

    近来参与了一个项目,软件主要的功能就是使用C#画矢量图,然后导出到Word、Excel、Powerpoint中,并且能够再次被编辑。以下是我们的解决过程:

    首先应该确定在Office文档中可编辑图形使用的格式;学习了相关资料,了解到Office文档主要支持三种矢量图的格式:1、VML图形,2、WMF文件格式,3、EMF文件格式。由于VML图开一般使用HTML语言进行描述,不便于进行操作,因此决定采用WMF和EMF文件格式。

    接下来的工作就是要让C#根据提供的数据生成WMF或EMF格式的矢量图形;学习了C#提供的GDI+绘图类库,GDI+可以绘制矢量图形,代码示例如下:
  

/// <summary>
  
/// 导出为 Emf 或 Wmf 文件
  
/// </summary>
  
/// <param name="filePath">文件路径</param>
  
/// <returns>是否成功</returns>

  private bool Export(string filePath)
  
{
   
try
   
{
    Bitmap bmp 
= new Bitmap(220,220);
    Graphics gs 
= Graphics.FromImage(bmp);
    Metafile mf  
= new Metafile(filePath,gs.GetHdc());

    Graphics g 
= Graphics.FromImage(mf);

    Draw(g);

    g.Save();
    g.Dispose();
    mf.Dispose();

    
return true;
   }

   
catch
   
{
    
return false;
   }

  }

  
/// <summary>
  
/// 绘制图形
  
/// </summary>
  
/// <param name="g">用于绘图的Graphics对象</param>

  private void Draw(Graphics g)
  
{
   HatchBrush hb 
= new HatchBrush(HatchStyle.LightUpwardDiagonal, Color.Black, Color.White);

   g.FillEllipse(Brushes.Gray,10f,10f,
200,200);
   g.DrawEllipse(
new Pen(Color.Black,1f),10f,10f,200,200);

   g.FillEllipse(hb,30f,95f,
30,30);
   g.DrawEllipse(
new Pen(Color.Black,1f),30f,95f,30,30);

   g.FillEllipse(hb,160f,95f,
30,30);
   g.DrawEllipse(
new Pen(Color.Black,1f),160f,95f,30,30);

   g.FillEllipse(hb,95f,30f,
30,30);
   g.DrawEllipse(
new Pen(Color.Black,1f),95f,30f,30,30);

   g.FillEllipse(hb,95f,160f,
30,30);
   g.DrawEllipse(
new Pen(Color.Black,1f),95f,160f,30,30);

   g.FillEllipse(Brushes.Blue,60f,60f,
100,100);
   g.DrawEllipse(
new Pen(Color.Black,1f),60f,60f,100,100);

   g.FillEllipse(Brushes.BlanchedAlmond,95f,95f,
30,30);
   g.DrawEllipse(
new Pen(Color.Black,1f),95f,95f,30,30);

   g.DrawRectangle(
new Pen(System.Drawing.Brushes.Blue,0.1f),6,6,208,208);

   g.DrawLine(
new Pen(Color.Black,0.1f),110f,110f,220f,25f);
   g.DrawString(
"剖面图",new Font("宋体",9f),Brushes.Green,220f,20f);
}


 产生的图形如下:

 放大后效果:

 在Word 中编辑图形:


至此,实现了该软件的技术要求功能。

posted @ 2006-08-10 14:45 无涯 阅读(6995) 评论(14) 编辑 收藏

 回复 引用 查看   
#1楼2006-08-10 18:09 | sanni:mylove      
good
 回复 引用   
#2楼2006-08-11 13:39 | lovebanyi[未注册用户]
不错
 回复 引用 查看   
#3楼2006-08-11 17:48 | 编写人生      
强,这样也可以
 回复 引用   
#4楼2006-10-18 08:44 | sandcrazy[未注册用户]
非常感谢
受益颇多

 回复 引用   
#5楼2006-10-26 17:10 | ABC[匿名][未注册用户]
没有实质性的意义,作用不大!
 回复 引用 查看   
#6楼[楼主]2006-10-26 17:22 | 无涯      
@ABC[匿名]
这个主要是因为客户要求图形要导到Office文档中,并且可以进行再调整,所以只能通过这种矢量图的方式来实现.

同时这种方式生成的矢量图可以保存为MS的Emf和Wmf 两种图元格式,优点是可以无限放大图形而不会降低图形质量.

 回复 引用   
#7楼2006-11-10 11:49 | 斯[未注册用户]
@无涯
Metafile image = new Metafile(filename1)
Graphics.FromImage(Image image);
一运行上面的语句,就报内存不足,即使我用的.emf文件很小,也一样。
请问这个是什么原因?

 回复 引用   
#8楼2007-04-09 11:15 | buaa[未注册用户]
多谢
 回复 引用   
#9楼2007-06-30 22:36 | kingjiang[未注册用户]
Bitmap bmp = new Bitmap(220,220);

这句话其实是没用的,比如画的是EMF格式的图片,它会根据图片的实际大小自动调整画出来的图片的大小,也就是说上面设的220,220是根本不起作用的。
如果想控制输出的图片的大小(指的是画图区域的大小,不是文件本身多少字节的大小),应该修改程序中的这句话:
Metafile mf = new Metafile(filePath,gs.GetHdc());

改为:
Rectangle rect = new Rectangle(0,0,70,80);
Metafile mf = new Metafile(filePath,gs.GetHdc(),rect,MetafileFrameUnit.Pixel);
以上两句代码中的70,80就是图片区域大小,分别代表长,高。


kingjiang
jiangbiao0827@gmail.com

 回复 引用   
#10楼2007-11-21 10:11 | richie[未注册用户]
不错,顶一下,有帮助
 回复 引用   
#11楼2007-11-30 02:52 | 上帝凝视A[未注册用户]
不错,可不可以不用bmp,直接将元文件绘制在窗体上?
 回复 引用   
#12楼2008-06-17 20:28 | socg[未注册用户]
没有实质性的意义,作用不大!

我主要是关心怎么从Wmf文件中读出里面的内容(例如:直线,矩形,圆形)

 回复 引用   
#13楼2009-09-03 17:44 | lenowang[未注册用户]
很好,很强大~!
 回复 引用 查看   
#14楼2010-01-20 09:59 | 元宝      
请教楼主一个偏门问题,用EMF如何绘制出调色版为二值的图像,就是黑白二值的失量图,比较急,谢谢!! yuanbao2006@qq.com

开源代码搜索引擎: