我也为这个问题苦苦挣扎了一段时间。这周我再次开始研究这个问题,并开始编写一个小的测试应用程序来隔离问题。我只需进行一些绘图操作就可以触发光栅化。
准确地说,是四个矩形、一个椭圆形和一条直线。
static void Main(string[] args)
{
var printers = new LocalPrintServer().GetPrintQueues(new[] { EnumeratedPrintQueueTypes.Local, EnumeratedPrintQueueTypes.Connections });
PrintQueue defaultPrinter = LocalPrintServer.GetDefaultPrintQueue();
PrintQueue printerToUse = printers.FirstOrDefault(p => p.Name.Contains("PDFCreator")) ?? defaultPrinter; // Use PDFCreator if available.
PrintTicket ticket = printerToUse.DefaultPrintTicket;
XpsDocumentWriter writer = PrintQueue.CreateXpsDocumentWriter(printerToUse);
writer.Write(CreateVisual(), ticket);
}
private static Visual CreateVisual()
{
var visual = new DrawingVisual();
using (DrawingContext dc = visual.RenderOpen())
{
var pen = new Pen(Brushes.Black, 3);
var opacityBrush = new SolidColorBrush { Color = Colors.Violet, Opacity = 0.7 };
dc.PushClip(new RectangleGeometry(new Rect(20, 20, 150, 150)));
dc.DrawLine(pen, new Point(0, 0), new Point(200, 300));
dc.DrawEllipse(new SolidColorBrush(Colors.LightGreen), pen, new Point(50, 80), 50, 70);
dc.DrawRectangle(new SolidColorBrush(Colors.LightBlue), pen, new Rect(10, 100, 100, 100));
dc.DrawRectangle(new SolidColorBrush(Colors.LightPink), pen, new Rect(40, 120, 100, 100));
dc.DrawRectangle(new SolidColorBrush(Colors.LightGray), pen, new Rect(60, 140, 100, 100));
dc.DrawRectangle(opacityBrush, pen, new Rect(80, 160, 100, 100));
}
return visual;
}
完整的测试应用程序可以从以下位置下载here http://helgo.net/salle/misc/WpfPrintingRasterizationTestApp.zip(VS 2010 解决方案)。
测试时我正在打印到PDF创建器 http://sourceforge.net/projects/pdfcreator/,一个虚拟 PDF 打印机,可防止大量纸张使用。但我用真实的物理打印机得到了相同的结果。然而,使用这个例子很难注意到纸上的差异,真实世界案例可能更引人注目(pic1 https://i.stack.imgur.com/JdBzb.png, pic2 https://i.stack.imgur.com/YhVHv.png).
Here is a screenshot of the result:
When you zoom in the PDF you see that the rectangles and ellipse is no longer in vector format and become blurry.
光栅化的条件
似乎很难定义。我和布豪尔有同样的经历,即不透明度和剪切似乎经常触发光栅化。我的示例确实包括这两个(在尝试触发光栅化时故意使用了这些)。并不是说任何这些都需要存在才能发生光栅化。
不透明度可能导致光栅化是有道理的,但您认为与该问题无关的其他一些细微变化实际上可以“阻止”光栅化的发生。就像在我的例子中改变笔的粗细一样(截屏 https://i.stack.imgur.com/ekTEA.png)。以某种方式消除光栅化条件的其他更改是更改绘图操作的顺序、删除任何操作,当然还有删除不透明度或剪切。
解决方法
我发现生成 XPS 文件并从微软 XPS 查看器即使使用完全相同的图形和打印机,实际上也会产生无光栅输出。
private static void GenerateXps()
{
var xpsDoc = new XpsDocument("wpf_printing_raster_test.xps", FileAccess.ReadWrite);
XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(xpsDoc);
writer.Write(CreateVisual());
xpsDoc.Close();
}
截屏here https://i.stack.imgur.com/f5jgv.png.
因此,您可以生成 XPS och,然后以编程方式指示,而不是直接从代码中打印微软 XPS 查看器为您打印 XPS。
这当然是一种黑客行为,而不是最佳解决方案。但如果没有找到修复或真正的解决方案(我自己还没有尝试过),如果有人有一个强制从 Microsoft XPS Viewer 进行打印的好方法,我会很感兴趣。
我还想知道即使从 Microsoft XPS Viewer 进行打印,是否有人仍然会遇到光栅化打印输出。
作为一个长远目标,我尝试在我的测试应用程序中加载 XPS 文件并打印它(code http://pastebin.com/4BDJ4dV7)。但这不起作用,仍然得到光栅化打印输出。
解决方案?
我认为这不是打印机驱动程序问题。当光栅化发生时,它会发生在所有打印机上,无一例外。我尝试过 4-5 台不同的打印机,价格从 100 美元起HP 1020到 6000 美元柯尼卡美能达 C360和一些虚拟打印机。
该解决方法还表明微软 XPS 查看器向打印机驱动程序发送与直接 WPF 打印不同的内容。
我们真的应该尝试让微软看看这个,它被归档为bug http://connect.microsoft.com/VisualStudio/feedback/details/488580/printing-complex-visuals-and-rasterization时间回到2009年,但什么也没发生。希望重现该问题的一个简洁的小代码示例会有所帮助。