【问题标题】:Is there a lightweight way to include GDI rendered content when printing with WPF?使用 WPF 打印时是否有一种轻量级的方法来包含 GDI 呈现的内容?
【发布时间】:2011-12-18 07:14:15
【问题描述】:

我从事的一个项目有一些预先存在的报告,这些报告通过 MFC 的打印支持打印,并通过 GDI 或多或少地直接呈现到打印机 DC。我们已经开始通过 WPF/XAML 做一些新的(不相关的)报告,因为无论如何我们都在将新的 UI 转换为 WPF,并且使用它进行布局要好得多。

另一只鞋终于掉了,我需要在现有的打印报告中添加一些新功能,而新功能实际上需要使用 WPF 来实现。我们现有的 WPF 报告是通过通过 XpsDocumentWriter 发送到 XpsDocument(内存中,而不是磁盘上)的 XAML 页面实现的。我希望能够继续使用这种策略,并采取编写 WPF/XAML 报告的方法,这些报告恰好有一些通过 GDI 呈现的页面。

我第一次天真的尝试是在 XpsDocumentWriter 中呈现的 UIElement 中嵌入 HwndHost,但这似乎不起作用。不足为奇,但值得一试。

下一个明显的解决方案是 IMO,将 GDI 图形渲染为适当大小和缩放的位图,并将该位图渲染到 XpsDocument 中的页面。这可行,但页面大小的位图(尤其是内存中的位图)似乎是导致内存使用率高且速度较慢的计算机性能不佳的原因。

理想情况下,我希望将 GDI 内容呈现为元文件或其他可以转换为 XPS 的矢量格式。但这必须是一个每次都有效的自动过程,因为它只是一个文档打印功能。 OTOH 它是内部用户的应用程序,因此我们可以忍受一些性能下降

WPF 开发不是我的主要任务,因此我将自己描述为对底层细节没有太多详细了解的新手。我只是想确保在我恢复使用位图作为传输媒介之前没有遗漏一些明显的东西,尽管到目前为止我还没有在我的搜索中找到任何其他合适的选项。

有什么我应该调查的吗?

【问题讨论】:

    标签: wpf printing interop gdi


    【解决方案1】:

    这样做的一种方法是在 WPF 中创建一个 WriteableBitmap 并将 GDI 绘制的图像直接 blit 到它,以便它可以在您的 XPS 文档中呈现。第一步可能是直接从 GDI DC 执行 blit(获取指向 GDI DC 的指针、指向 WriteableBitmap 的指针并使用 Platform Invoke 调用 memcpy)。以后的工作可能涉及将 MFC GDI 绘图转换为 vanilla WPF(使用具有类似 gdi 的绘图方法的库,如 WriteableBitmapEx)。

    虽然上面的第一种方法会涉及两个位图,但这是我目前能想到的最好的方法,无需大量重写。第二种方法可能开箱即用,也可能不开箱即用,因为 WriteableBitmaps 的绘图支持不如 GDI 扩展。我刚刚想到的最后一种方法是通过 Platform Invoke 使用 GDI 并直接在 WriteableBitmap 表面上绘制。这将允许移植而无需大量重写,并为您提供所需的性能,同时保持代码熟悉。

    【讨论】:

    • 谢谢。我曾希望通过位图避免手动光栅化(主要是因为在处理打印时像素分辨率令人头疼),但似乎这可能是唯一实用的方法。我想这使得我的问题的答案是“否”。
    • 恐怕是,wpf和gdi中的渲染引擎是完全不同的。让我问一下,如果您已经在 gdi 中找到了解决方案(打印出来看起来不错吗?),那么您能否不将该代码包装到 c++ dll 中并进行修改以应对不同的分辨率?即传递一个宽度、高度、dpi 给它。然后在每次用户更改 dpi 或渲染目标大小时从 c# 中调用它来绘制并执行 blit 到 WrirableBitmap?
    • 对于 Windows 7,xps 打印驱动程序直接内置了 gdi 支持。遗憾的是不适合 vista 或 xp:blogs.technet.com/b/print/archive/2009/12/01/…
    • 当前的 GDI 解决方案用于打印并且已经处理不同的分辨率。我对位图 blit 方法的担心是您概述的简单方法所需的位图大小,考虑到我需要在 GDI 中呈现整个页面,而不仅仅是页面的一小部分。这可能不是问题,但 600 DPI 的整页相当大,即使是灰度。不过我可能太担心了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-16
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    • 2020-10-14
    • 1970-01-01
    • 2018-08-20
    相关资源
    最近更新 更多