繁体   English   中英

在Win7&Vista上使用PrintDocument将多个图像打印到传真虚拟打印机会导致TIFF损坏

[英]Printing multiple images to the Fax virtual printer using PrintDocument on Win7&Vista results in corrupt TIFF

我有一个应用程序,该应用程序使用PrintDocument将多个图像作为单个打印作业打印,每页一个图像。 我有一个非常具体但通用的配置问题,想知道如何纠正它。

该代码在我可以访问的任何物理打印机和所有台式机Windows操作系统上的Microsoft XPS Document Writer上都可以正常工作。 但是,打印到传真虚拟打印机(在Windows操作系统上是标准的一种)只能在Windows XP和Windows 8上工作。当我在Windows Vista或Windows 7上打印到传真打印机时,表明已成功打印。 但是,如果有多个页面,并且您打开创建的.tif图像,则Windows Photo Viewer会说

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();
}

这仅仅是这些操作系统上的传真打印机的问题,还是以上代码有问题? 我该如何解决这个问题?

此Microsoft修补程序没有专门提及传真,但确实具有正确的错误消息,因此我尝试应用它。 没关系。

我在Microsoft合作伙伴支持社区中追求这一点。 最终的答复是,他们已经确认了该问题,并且“升级工程师正在解决此问题”。

我想出的解决方法是使用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需要显式处理),并且我正在加载相对较大的图像,所以它的确似乎会稍微降低内存使用率,最终在大型作业上会变慢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM