C# 生成多个图形对象以并行使用
我正在尝试创建一个图形对象,我可以使用它来绘制图元文件,但我不确定最好的方法是什么。最终,图元文件将包含在Word文档中,我们希望它们在打印时外观良好 起初我有这样的想法:C# 生成多个图形对象以并行使用,c#,gdi+,metafile,C#,Gdi+,Metafile,我正在尝试创建一个图形对象,我可以使用它来绘制图元文件,但我不确定最好的方法是什么。最终,图元文件将包含在Word文档中,我们希望它们在打印时外观良好 起初我有这样的想法: var ms = new MemoryStream(); using (var mfG = System.Drawing.Graphics.FromHwndInternal(IntPtr.Zero)) using (Metafile mf = new Metafile(ms, mfG.GetHdc(), EmfType.Em
var ms = new MemoryStream();
using (var mfG = System.Drawing.Graphics.FromHwndInternal(IntPtr.Zero))
using (Metafile mf = new Metafile(ms, mfG.GetHdc(), EmfType.EmfPlusOnly, "Chart"))
using (var g = System.Drawing.Graphics.FromImage(mf))
{
// do some drawing
}
这是可行的,但我想并行处理多个图像,在这种情况下会产生错误,因为它们都试图使用相同的图形对象
因此,我尝试(基于联机上的一些建议来创建图形对象):
但它仍然存在同样的问题。显然,CreateMeasurementGraphics
每次都为您提供相同的图形对象
我可以用
锁
包装代码,让其他线程等待。也许我应该。但是,有没有更好的方法来生成独立的图形
对象,从而生成像样的可打印图元文件?我不知道,我的回答是否对您有帮助,但您不能从多个线程绘制到同一图形对象
可以执行的操作:可以使用链接的图形对象创建多个图元文件,并且可以并行绘制到不同的文件。显然,每个线程都必须使用自己的MetaFileGraphics duo
最后,您可以使用单个图形对象和“DrawImageUnscaled”方法组合图像
示例(将尝试将文件写入D:。您可能希望更改目标):
使用系统;
使用系统图;
使用系统、绘图、成像;
使用System.IO;
使用System.Threading.Tasks;
使用System.Windows.Forms;
命名空间MetaFileDrawTest
{
公共部分类Form1:Form
{
公共表格1()
{
初始化组件();
}
受保护的覆盖无效OnPaint(PaintEventArgs e)
{
基础漆(e);
Pen[]p=新笔[]{Pens.Black,Pens.Red,Pens.Green};
//并行绘制三个图元文件。
对于(0,3,i=>
{
使用(var ms=new MemoryStream())
{
使用(var mfG=System.Drawing.Graphics.fromHwnInternal(IntPtr.Zero))
{
使用(图元文件mf=新图元文件(ms,mfG.GetHdc(),EmfType.EmfPlusOnly,“图表”))
{
使用(VARG=System.Drawing.Graphics.FromImage(mf))
{
//每次画一条稍有不同的线,看看有什么不同。。。
g、 抽绳(p[i],10*i,10,100,100);
}
//将图元文件保存到光盘中。(也可以将其保存在内存中)
mf.Save(“D:\\test”+i+“.wmf”);
}
}
}
});
//将三个图元文件绘制到表单中(仅查看它们的外观)
对于(int i=0;i
using (var mfG = new System.Drawing.Printing.PrinterSettings().CreateMeasurementGraphics())
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace MetaFileDrawTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Pen[] p = new Pen[] { Pens.Black, Pens.Red, Pens.Green };
// Draw to three MetaFiles in Parallel.
Parallel.For(0, 3, i =>
{
using (var ms = new MemoryStream())
{
using (var mfG = System.Drawing.Graphics.FromHwndInternal(IntPtr.Zero))
{
using (Metafile mf = new Metafile(ms, mfG.GetHdc(), EmfType.EmfPlusOnly, "Chart"))
{
using (var g = System.Drawing.Graphics.FromImage(mf))
{
// Draw a slightly different line each time to see a difference...
g.DrawLine(p[i], 10 * i, 10, 100, 100);
}
// Save the Metafile to the disc. (You might keep it in memory as well)
mf.Save("D:\\test" + i + ".wmf");
}
}
}
});
// Draw the three metafiles to the form (just to see how they look like)
for (int i = 0; i <= 2; i++)
{
e.Graphics.TranslateTransform(100 * (i + 1), 0);
e.Graphics.DrawImageUnscaled(Image.FromFile("D:\\test" + i + ".wmf"), 0, 0);
e.Graphics.ResetTransform();
}
// Create a file metafile to draw all single images to (one by one)
using (var ms2 = new MemoryStream())
{
using (var mfG = System.Drawing.Graphics.FromHwndInternal(IntPtr.Zero))
{
using (Metafile mf = new Metafile(ms2, mfG.GetHdc(), EmfType.EmfPlusOnly, "Chart"))
{
using (var g = System.Drawing.Graphics.FromImage(mf))
{
g.DrawImageUnscaled(Image.FromFile("D:\\test0.wmf"), 0, 0);
g.DrawImageUnscaled(Image.FromFile("D:\\test1.wmf"), 0, 0);
g.DrawImageUnscaled(Image.FromFile("D:\\test2.wmf"), 0, 0);
}
// Save the combined file to disc
mf.Save("D:\\complete.wmf");
// draw the combined file to the form.
e.Graphics.DrawImageUnscaled(mf, 0, 0);
}
}
}
}
}