我正在使用 C# 和 PDFium 库将 PDF 打印到特定的标签打印机。当我通过 Chrome、Edge 或我的应用程序打印此 PDF 时,质量值得怀疑。当我通过 Adobe 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),但如果有人需要,我可以发布它们。