我在WPF中遇到很多问题,其中打印的项目的特定组合将突然触发打印机输出的光栅化(导致丑陋和巨大的打印机输出,并且可能导致打印每页需要30秒)。我发现通常在控件上设置任何级别的不透明度都会引发这种情况。我忘记了其他所有的事情(我相信使用带有剪辑的画布也能做到这一点),但是现在我遇到了另一个问题,一个带有平铺图像画填充边框的堆叠面板......等等。现在再次导致这种光栅化。
所以在我再次尝试找出什么触发什么等之前,我想知道是否有人知道关于哪些特定项目可能触发这一点的确切信息来源?或者也许某种方式可以进入系统,让我至少试着想出来......
到目前为止,这是我在WPF工作多年的必须令人沮丧的部分。
更新:我今天发现只是在画布中包含一个图像也会导致它也被光栅化。不一致,但有时候。可能与尺寸有关,或者可能是否被裁剪等等。唉。
我经常打印到PDF文件,但我发现adobe acrobat打印机和其他物理打印机之间的行为几乎相同。
答案 0 :(得分:8)
我一直在努力解决这个问题。本周我开始再次研究这个问题并开始编写一个小测试应用程序来隔离问题。我只用几个绘图操作就可以触发光栅化。 四个矩形,一个椭圆和一条准确的线。
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(VS 2010解决方案)下载完整的测试应用程序。
在测试时我正在打印PDFCreator,这是一款虚拟PDF打印机,可以防止大量使用纸张。但是我用真正的物理打印机得到了相同的结果。使用此示例很难注意到纸上的差异,但真实世界的情况可能更明显(pic1,pic2)。
以下是结果的屏幕截图: 当您放大PDF时,您会看到矩形和椭圆不再是矢量格式并变得模糊。
似乎很难定义。我和boomhauer有着相同的经验,不透明度和裁剪似乎经常引发光栅化。我的例子确实包括了这两种(当试图触发光栅化时那种故意使用的那种)。并不是说任何一个都需要存在才能进行光栅化。
有意义的是,不透明度可能会导致光栅化,但您认为与该问题无关的其他一些细微变化实际上可以“防止”光栅化发生。就像在我的示例中更改笔的厚度(screenshot)。以某种方式删除光栅化条件的其他更改是更改绘制操作的顺序,删除任何操作,当然还要删除不透明度或剪切。
我发现生成XPS文件并从 Microsoft XPS Viewer 打印它实际上会产生无光栅输出,即使使用了完全相同的绘图和打印机。
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。
因此,不是直接从代码中打印,而是生成XPS och,然后以编程方式指示<em> Microsoft XPS Viewer 为您打印XPS。
这当然是一个黑客而不是最佳解决方案。但是如果没有找到修复或真正的解决方案(如果没有找到修复或真正的解决方案),如果有人有一个很好的方法从Microsoft XPS Viewer强制打印,我会感兴趣。
我也有兴趣知道即使从Microsoft XPS Viewer打印,有人仍然会经历光栅化打印输出。
作为一个远景,我试图在我的测试应用程序中加载XPS文件并打印它(code)。但这不起作用,仍然有光栅化的打印输出。
我认为这不是打印机驱动程序问题。发生光栅化时,它会在所有打印机上发生,没有异常。我尝试过4-5种不同的打印机,从100美元 HP 1020 到6000美元 Konica Minolta C360 以及一些虚拟打印机。
解决方法还表明 Microsoft XPS Viewer 会向打印机驱动程序发送不同的内容,然后直接进行WPF打印。
我们应该真的试图让微软看看这个,它在2009年被提交为bug,但一无所获。希望重现问题的小简洁代码示例会有所帮助。