我有一个应用程序,应用程序使用PrintDocument
将多个图像作为单个打印作业打印,每页一个图像。我遇到了一个非常具体但常见的配置问题,我想知道如何纠正它。
代码在我可以访问的任何物理打印机和所有桌面Windows操作系统上的Microsoft XPS Document Writer上都可以正常运行。但是,打印到传真虚拟打印机(Windows操作系统上标准的打印机)仅适用于Windows XP和Windows 8.当我在Windows Vista或Windows 7上打印到传真打印机时,它表示打印成功;但是,如果有多个页面并且您打开了Windows照片查看器所创建的.tif图像
Windows Photo Viewer无法打开此图片,因为该文件似乎已损坏,已损坏或过大。
该消息是来自Windows 7的消息,Vista上的文本可能略有不同。如果只有一个图像(因此是一个页面),它可以正常工作。
如果发送传真,则会显示空白。我也尝试在GIMP中打开.tif图像并使用ImageMagick处理它,这两个图像都失败,表明它是一个坏的.tif文件。
这是产生问题的代码,已删除一些稳健性以允许更简洁的示例。
internal void Print( string printerName )
{
PrintDocument printDocument = new PrintDocument
{
PrinterSettings = new PrinterSettings {PrinterName = printerName}
};
IEnumerable<string> filesToPrint = new[]{"File1.png", "File2.png"};
IEnumerator<string> enumerator = filesToPrint.GetEnumerator();
enumerator.MoveNext()
printDocument.PrintPage += (sender, args) =>
{
string fileName = enumerator.Current;
using (var img = System.Drawing.Image.FromFile(fileName))
{
args.Graphics.DrawImage(img, args.PageBounds);
}
var moveNext = enumerator.MoveNext();
args.HasMorePages = moveNext;
if (!moveNext)
{
enumerator.Dispose();
}
};
printDocument.Print();
}
这仅仅是这些操作系统上传真打印机的问题,还是上述代码有问题?我该如何解决这个问题?
This Microsoft hotfix没有特别提及传真,但确实有正确的错误消息,所以我尝试应用它。它没有任何区别。
答案 0 :(得分:0)
我在微软合作伙伴支持社区中追求这一点。最终的答复是他们已经确认了这个问题并且“升级工程师正在解决这个问题。”
我自己提出的解决方法是使用System.Printing
而不是System.Drawing.Printing
进行打印。
internal override void Print(string printerName, string baseFilePath, string baseFileName)
{
using (var printQueue = GetPrintQueue(printerName))
{
XpsDocumentWriter xpsDocumentWriter = PrintQueue.CreateXpsDocumentWriter(printQueue);
IEnumerable<string> filesToPrint = GetFilesToPrint(baseFilePath, baseFileName);
PrintUsingCollator(xpsDocumentWriter, filesToPrint);
}
}
private static void PrintUsingCollator(XpsDocumentWriter xpsDocumentWriter,
IEnumerable<string> filesToPrint)
{
SerializerWriterCollator collator = xpsDocumentWriter.CreateVisualsCollator();
collator.BeginBatchWrite();
foreach (var fileName in filesToPrint)
{
Image image = CreateImage(fileName);
ArrangeElement(image);
collator.Write(image);
}
collator.EndBatchWrite();
}
/// <remarks>
/// This method needs to be called in order for the element to print the right size.
/// </remarks>
private static void ArrangeElement(UIElement element)
{
var box = new Viewbox {Child = element};
box.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
box.Arrange(new Rect(box.DesiredSize));
}
System.Printing
是基于WPF的新API。在这种特殊情况下它的缺点是它是内存使用。因为System.Windows.Controls.Image
是GC编辑的(其中System.Drawing.Image
需要显式处理)并且我正在加载相对较大的图像,所以它似乎会稍微破坏内存使用量,并最终在大型作业上稍慢一些。 / p>