簡體   English   中英

XPS打印質量C#與XPS查看器

[英]XPS Print Quality C# vs. XPS viewer

我的C#應用​​程序中遇到打印質量問題。 我有一個XPS文件(基本上只是一頁紙的圖像,最初是掃描的黑白圖像),我試圖通過C#應用程序將其打印到IBM InfoPrint Mainframe驅動程序。 我已經使用許多其他打印驅動程序進行了打印,但從未遇到過問題,但是此驅動程序通過其創建的AFP文件為我提供了出色的質量。 如果我在Microsoft XPS Viewer應用程序中打開相同的文件並打印到相同的驅動程序,則質量看起來不錯。

盡管問題仍然存在,但我仍嘗試工作在C#應用程序中嘗試了3種或4種不同的打印方法。 原始代碼做了這樣的事情(為簡潔起見):

        System.Windows.Xps.XpsDocumentWriter writer = PrintQueue.CreateXpsDocumentWriter(mPrintQueue);
        mCollator = writer.CreateVisualsCollator();
        mCollator.BeginBatchWrite();
        ContainerVisual v = getContainerVisual(xpsFilePath);
        //tried all sorts of different options on the print ticket, no effect
        mCollator.Write(v,mDefaultTicket);

該代碼(我已將其截斷了)中肯定有一些奇怪的問題,因此我嘗試了一些簡單得多的方法:

            LocalPrintServer localPrintServer = new LocalPrintServer();
            PrintQueue defaultPrintQueue = LocalPrintServer.GetDefaultPrintQueue();
            PrintSystemJobInfo xpsPrintJob = defaultPrintQueue.AddJob("title", xpsDocPath, false);

結果相同。

我什至嘗試使用同樣質量較差的WCF打印對話框( http://msdn.microsoft.com/en-us/library/ms742418.aspx )。

我還沒有嘗試過的一個領域是使用老式的基礎打印API,但是我不確定為什么這樣做會有所不同。 我還有一個選擇,就是我的原始文檔是PDF,並且我有一個不錯的第三方庫,可以使我成為EMF文件。 但是,每次我嘗試將該EMF文件流式傳輸到打印機時,都會出現亂碼。

對於為什么會失去這種質量,如何解決或如何將EMF文件流式傳輸到打印驅動程序的任何想法,將不勝感激!

更新:另一注。 這個不錯的示例應用程序: http : //wrb.home.xs4all.nl/Articles_2010/Article_XPSViewer_01.htm遇到同樣的質量損失。 現在,我還執行了一些測試,在這些測試中,我直接打開PDF並將位圖渲染為打印文檔,結果圖像的模糊性相同。 如果我在Acrobat中打開PDF並進行打印,它們看起來會很好。

因此,要解決此問題,根據您在C#中的打印方式,IBM Infoprint驅動程序(至少在這里使用的方式)似乎具有完全不同的質量。

在此問題中,我使用的是:

System.Windows.Documents.Serialization.Write(Visual, PrintTicket);

我完全改變了方法,完全刪除了XPS,並獲得了文檔的emf(Windows圖元文件)格式,然后使用Windows打印事件處理程序將該emf文件發送到Windows打印機:

using (PrintDocument pd = new PrintDocument())
{
    pd.DocumentName = this.mJobName;
    pd.PrinterSettings.PrinterName = this.mPrinterName;
    pd.PrintController = new StandardPrintController();
    pd.PrintPage += new PrintPageEventHandler(DoPrintPage);
    pd.Print();
}

(我顯然在這里省略了很多代碼,但是您可以找到有關如何相對輕松地使用此方法的示例)

在我的測試中,大多數打印驅動程序對這兩種打印方法都同樣滿意,但是IBM Infoprint驅動程序對質量非常敏感。 一種可能的解釋是,要求Infoprint打印機配置有奇怪的固定DPI,並且它的轉換工作可能相對較差。

編輯:請求了更詳細的示例代碼,所以在這里。 請注意,獲取EMF文件是此方法的先決條件。 在這種情況下,我使用的是ABC PDF,它使您可以通過相對簡單的調用從PDF生成EMF文件。

   class AbcPrintEmf
{
    private Doc mDoc;
    private string mJobName;
    private string mPrinterName;
    private string mTempFilePath;
    private bool mRenderTextAsPolygon;
    public AbcPdfPrinterApproach(Doc printMe, string jobName, string printerName, bool debug, string tempFilePath, bool renderTextAsPolygon)
    {
        mDoc = printMe;
        mDoc.PageNumber = 1;
        mJobName = jobName;
        mPrinterName = printerName;
        mRenderTextAsPolygon = renderTextAsPolygon;
        if (debug)
            mTempFilePath = tempFilePath;
    }

    public void print()
    {
        using (PrintDocument pd = new PrintDocument())
        {
            pd.DocumentName = this.mJobName;
            pd.PrinterSettings.PrinterName = this.mPrinterName;
            pd.PrintController = new StandardPrintController();
            pd.PrintPage += new PrintPageEventHandler(DoPrintPage);
            pd.Print();
        }
    }

    private void DoPrintPage(object sender, PrintPageEventArgs e)
    {
        using (Graphics g = e.Graphics)
        {
            if (mDoc.PageCount == 0) return;
            if (mDoc.Page == 0) return;

            XRect cropBox = mDoc.CropBox;
            double srcWidth = (cropBox.Width / 72) * 100;
            double srcHeight = (cropBox.Height / 72) * 100;
            double pageWidth = e.PageBounds.Width;
            double pageHeight = e.PageBounds.Height;
            double marginX = e.PageSettings.HardMarginX;
            double marginY = e.PageSettings.HardMarginY;
            double dstWidth = pageWidth - (marginX * 2);
            double dstHeight = pageHeight - (marginY * 2);

            // if source bigger than destination then scale
            if ((srcWidth > dstWidth) || (srcHeight > dstHeight))
            {
                double sx = dstWidth / srcWidth;
                double sy = dstHeight / srcHeight;
                double s = Math.Min(sx, sy);
                srcWidth *= s;
                srcHeight *= s;
            }

            // now center
            double x = (pageWidth - srcWidth) / 2;
            double y = (pageHeight - srcHeight) / 2;

            // save state
            RectangleF theRect = new RectangleF((float)x, (float)y, (float)srcWidth, (float)srcHeight);

            int theRez = e.PageSettings.PrinterResolution.X;

            // draw content
            mDoc.Rect.SetRect(cropBox);
            mDoc.Rendering.DotsPerInch = theRez;
            mDoc.Rendering.ColorSpace = "RGB";
            mDoc.Rendering.BitsPerChannel = 8;

            if (mRenderTextAsPolygon)
            {
                //i.e. render text as polygon (non default)
                mDoc.SetInfo(0, "RenderTextAsText", "0");
            }

            byte[] theData = mDoc.Rendering.GetData(".emf");
            if (mTempFilePath != null)
            {
                File.WriteAllBytes(mTempFilePath + @"\" + mDoc.PageNumber + ".emf", theData);
            }
            using (MemoryStream theStream = new MemoryStream(theData))
            {
                using (Metafile theEMF = new Metafile(theStream))
                {
                    g.DrawImage(theEMF, theRect);
                }
            }

            e.HasMorePages = mDoc.PageNumber < mDoc.PageCount;
            if (!e.HasMorePages) return;

            //increment to next page, corrupted PDF's have occasionally failed to increment
            //which would otherwise put us in a spooling infinite loop, which is bad, so this check avoids it
            int oldPageNumber = mDoc.PageNumber;
            ++mDoc.PageNumber;
            int newPageNumber = mDoc.PageNumber;
            if ((oldPageNumber + 1) != newPageNumber)
            {
                throw new Exception("PDF cannot be printed as it is corrupt, pageNumbers will not increment properly.");
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM