-1

我正在尝试创建一个可用于绘制元文件的图形对象,但我不确定最好的方法是什么。最终,元文件将包含在 Word 文档中,我们希望它们在打印时看起来不错。

起初我有这样的事情:

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 
}

这可行,但我想并行处理多个图像,在这种情况下会产生错误,因为它们都试图使用相同的图形对象。

所以我尝试了(基于一些在线创建图形对象的建议):

using (var mfG = new System.Drawing.Printing.PrinterSettings().CreateMeasurementGraphics())

但它仍然有同样的问题。显然CreateMeasurementGraphics每次都给你相同的图形对象。

我可以用 a 包装代码lock以使其他线程等待。也许我应该。但是有没有更好的方法来生成Graphics能够产生体面的可打印元文件的独立对象?

4

1 回答 1

0

我不知道,如果我的回答对你有任何帮助,但你不能从多个线程绘制到同一个 Graphics 对象。

您可以做什么:您可以使用链接的 Graphics 对象创建多个 MetaFile,并且可以并行绘制到不同的文件。显然每个线程都必须使用它自己的 MetaFile<->Graphics duo。

最后,您可以使用单个 Graphics 对象和“DrawImageUnscaled”方法组合图像。

示例(将尝试将文件写入 D:。您可能想要更改目标):

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);
                    }
                }
            }
        }
    }
于 2018-08-07T16:28:06.907 回答