【发布时间】:2020-06-26 11:47:12
【问题描述】:
我有一个 Win32 Direct2D 应用程序,用户可以在其中绘制图元以及加载和操作图片以创建风景。之后,可以打印风景或将其保存为 PDF 文件。
打印D2D内容的过程在这篇文章中有讲解,我也是这么实现的:https://docs.microsoft.com/en-us/windows/win32/direct2d/printing-and-command-lists
总之,打印通过将 D2D 内容渲染到 ID2D1CommandList 来进行,该 ID2D1CommandList 设置为 ID2D1DeviceContext 的目标。将场景渲染到 CommandList 后,我将其关闭,将其作为页面添加到 ID2D1PrintControl,关闭 ID2D1PrintControl(这会将所有命令发送到打印机),然后恢复我的 D2D 资源。 PDF 文件是通过相同的过程创建的,但我使用“Microsoft Print to PDF”作为我的打印机。
所有这些作品。但是,当包含大图片时,我注意到生成的 PDF 文件变得非常大。例如,我将一个 4000 x 3000 像素的 jpg 加载到我的应用程序中(它本身有 5 MB 文件大小),打印到 PDF --> PDF 将有 28 MB,打印作业需要几秒钟结束。在某些机器上,它甚至会崩溃(我认为 ID2D1PrintControl::AddPage(...) 函数或 ID2D1PrintControl::Close() 函数有时需要永远返回并且程序没有响应)。
现在,我知道 D2D 不能在内部使用像 jpg 这样的压缩图像,这就是为什么我首先从 jpg 文件创建一个 ID2D1Bitmap,这也是我在打印时使用的。
问题:有什么方法可以在 D2D 中的图像到达打印机之前对其进行压缩?我假设我的问题来自慢速机器无法正确处理的大型 PrintStreams(?)。由于分辨率很重要,我无法缩放图像!
我意识到 PDF 部分可能可以通过使用一些 PDF 创建库并使用原始压缩 jpg 并将其包含在 PDF 中来修复,但我真的想避免在通常使用 PDF 打印机时使用一些 PDF 库工作正常。
由于互联网上确实缺乏有关 D2D 打印问题的信息,因此我们将不胜感激。
编辑:我现在找到了一种在将图片发送到打印机之前对图片进行光栅化的方法,方法是降低 DPI 并绘制到第二个命令列表,以使生成的 PDF 文件更小。
剩下的最后一个问题是,在一些机器上,ID2D1PrintControl::AddPage(...) - 函数只是没有返回/它冻结了计算机。没有失败,没有成功,每当尝试用多张图片打印复杂的风景时。我还没有研究:打印机驱动程序,我可以尝试的所有各种打印机设置,这些机器上的 directX 版本(可能与此无关)。是否有人对可能导致 AddPage 函数不返回的原因有任何其他想法?是否有任何可能缺少的典型安装?可以选择作为第 4 和第 5 参数输入的 D2D1_TAG 是否有任何意义?
【问题讨论】:
-
您是否检查过:docs.microsoft.com/en-us/windows/win32/direct2d/… 您可能想尝试 96 DPI。否则,你有复制样本吗?
-
感谢您对文章和 DPI 设置的提示。我现在找到了一种通过显式设置 DPI 并使用我绘制第一个命令列表的第二个命令列表来栅格化我的图像的方法。然后,我打印第二个命令列表。生成的文件要小得多。所以谢谢你。一些机器上仍然存在的一个问题是 ID2D1PrintControl::AddPage - 函数没有返回。没有错误,没有成功,它只需要永远。关于什么可以使这个函数不返回的任何想法/有没有人遇到过这种行为?
-
您可以启用DX调试层。还可以在启用调试符号的情况下进入进程。也许您可以看到它似乎卡住的地方,并对正在发生的事情有所暗示。如果你可以复制,你应该把它发布到微软。您还应该在这个问题上回答自己,并创建另一个问题。