5

我正在使用 C# 和 PDFium 库将 PDF 打印到特定的标签打印机。当我通过 Chrome、Edge 或我的应用程序打印此 PDF 时,质量值得怀疑。当我通过 Adob​​e Reader 或 Foxit Reader 打印时,质量正是我想要的。

这是 imgur 上的差异图片:https ://i.imgur.com/gSnYcEE.jpg

我的应用程序是标有“网络打印”的应用程序。正如您在图像中看到的,它的质量与浏览器所做的相匹配。特别是右边的小文字是我关心的。

那么桌面 PDF 阅读器在打印时有何不同呢?

这是在 C# 中实际打印 PDF 的代码:

public static Boolean Print(PrintQueue printer, byte[] content, Boolean landscape)
{
    using (MemoryStream stream = new MemoryStream(content))
    {
        PdfDocument doc = PdfDocument.Load(stream);
        PrintDocument pd = GetPrintDocumentAsPDF(printer.Name, doc, landscape);
        pd.Print();
        return true;
    }
}

private static PrintDocument GetPrintDocumentAsPDF(String printerName, PdfDocument doc, Boolean landscape)
{
    PdfPrintMultiplePages multiPages = new PdfPrintMultiplePages(1, 1, landscape ? System.Windows.Forms.Orientation.Horizontal : System.Windows.Forms.Orientation.Vertical, 0);
    PdfPrintSettings settings = new PdfPrintSettings(PdfPrintMode.CutMargin, multiPages);

    PrintDocument pd = doc.CreatePrintDocument(settings);
    pd.PrinterSettings.PrinterName = printerName;

    Rectangle firstPage = GetSizeForDoc(doc, 0);

    pd.DefaultPageSettings.Landscape = landscape;

    // Find the closest matching media profile based on the size of the first page
    PaperSize bestFit = GetBestFitMediaProfile(firstPage.Width, firstPage.Height, landscape, pd.PrinterSettings.PaperSizes);

    if (bestFit != null)
    {
        pd.DefaultPageSettings.PaperSize = bestFit;
    }
    else
    {
        Util.RestLog("!!! No matching media profile. Using default !!!");
    }

    return pd;
}

/// <summary>
/// Calculates the size of a page from a document
/// </summary>
/// <param name="doc">the document to get the page from</param>
/// <param name="page">the page number to get the size for</param>
/// <returns>a rectangle with the width and height of the page</returns>
private static Rectangle GetSizeForDoc(PdfDocument doc, int page)
{
    // Calculate the actual size of the document
    SizeF docSize = doc.PageSizes[page];
    Rectangle docBounds = new Rectangle(0, 0, (int)Math.Floor(docSize.Width / DOT_PER_INCH * 100),
        (int)Math.Floor(docSize.Height / DOT_PER_INCH * 100));

    return docBounds;
}

/// <summary>
/// For a given width and height (of a document page), determines the smallest available media profile
/// that can be printed to while still encompassing the entire page
/// </summary>
/// <param name="width">width of the page to print</param>
/// <param name="height">height of the page to print</param>
/// <param name="mediaProfiles">the media profiles available on the print being printed to</param>
/// <returns></returns>
private static PaperSize GetBestFitMediaProfile(int width, int height, bool landscape, PrinterSettings.PaperSizeCollection mediaProfiles)
{
    PaperSize mediaProfile = null;
    double docLong = Math.Round((landscape ? width : height) * 1f, 2);
    double docShort = Math.Round((landscape ? height : width) * 1f, 2);

    double profileLong;
    double profileShort;

    foreach (PaperSize profile in mediaProfiles)
    {
        Util.RestLog("Found media profile: " + profile.Width + " x " + profile.Height);

        double profileWidth = Math.Round(profile.Width * 1f, 2);
        double profileHeight = Math.Round(profile.Height * 1f, 2);

        profileLong = landscape ? profileWidth : profileHeight;
        profileShort = landscape ? profileHeight : profileWidth;

        if (mediaProfile == null)
        {
            // Grab the first media profile that is larger than the document in both width and height
            if (profileLong >= docLong && profileShort >= docShort)
            {
                mediaProfile = profile;
            }
        }
        else
        {
            // If this profile is closer to the document size than the current one
            if (profileLong >= docLong && profileShort >= docShort &&
                GetArea(profileWidth, profileHeight) < GetArea(mediaProfile.Width, mediaProfile.Height))
            {
                mediaProfile = profile;
            }
        }
    }

    return mediaProfile;
}

/// <summary>
/// Calculates an area give a width and a height
/// </summary>
/// <param name="width">the width</param>
/// <param name="height">the height</param>
/// <returns>the area of the width and height</returns>
private static double GetArea(double width, double height)
{
    return width * height;
}

本质上,这样做的主要目的是为正在打印的 PDF 文档的大小选择正确的介质配置文件。我不相信任何人都需要查看与找到正确大小有关的方法(GetSizeForDoc 和 GetBestFitMediaProfile),但如果有人需要,我可以发布它们。

4

0 回答 0