该页面可以包含自动翻译的文本。

在 C# 和 VB.NET 中压缩 PDF 文档

在许多情况下,压缩和优化 PDF 文档是一个常见需求。更小的 PDF 文档更容易通过网络传输,存储成本也更低。减小 PDF 文件大小对于归档尤其重要。

在 C# 和 VB.NET 中优化 PDF 文档

用于优化 PDF 文档的 .NET 库

使用 Docotic.Pdf library 在 .NET Framework 和 .NET Core 应用程序中压缩 PDF 文档。该库可通过 NuGet 和我们的网站获取。请在 下载 C# .NET PDF 库 页面获取该库和一个免费、限时许可证密钥。

Docotic.Pdf 提供多种优化手段:

  • 优化 PDF 对象
  • 删除重复的 PDF 对象(字体、图像等)
  • 压缩图像
  • 字体子集化
  • 删除元数据
  • 删除结构信息
  • 删除未使用的资源
  • 删除私有应用程序数据
  • 展平表单字段和批注
  • 取消嵌入字体

你可以使用以上所有方法为 PDF 文档获得最佳压缩比。查看 在 .NET 中压缩 PDF 文档 示例,了解这些技术的实际效果。

让我们更详细地回顾这些压缩方法。

优化 PDF 对象

从内部来看,PDF 文件是低级 PDF 对象的集合:字典、流、数组等。保存 PDF 文件时,Docotic.Pdf 默认会应用以下无损优化:

  • 使用 Flate 编码压缩 PDF 流
  • 删除未使用的 PDF 对象
  • 内联间接 PDF 对象
  • 写入不带格式的 PDF 对象
  • 将 PDF 对象打包到压缩对象流中

此示例演示如何在 C# 中优化 PDF 对象:

using BitMiracle.Docotic.Pdf;

using var pdf = new PdfDocument("input.pdf");
var saveOptions = new PdfSaveOptions();

// 这些选项默认启用并会隐式应用:
//saveOptions.Compression = PdfCompression.Flate;
//saveOptions.RemoveUnusedObjects = true;
//saveOptions.OptimizeIndirectObjects = true;
//saveOptions.UseObjectStreams = true;
//saveOptions.WriteWithoutFormatting = true;

pdf.Save("compressed.pdf", saveOptions);

所有这些优化都不会影响 PDF 文档的可见内容(文本、图像、书签以及其他内容)。它们只影响 PDF 对象在输出 PDF 文件中的写入和压缩方式。

删除未使用的 PDF 对象对下面讨论的其他技术很重要。除非你有充分理由保留未使用对象,否则不要将 PdfSaveOptions.RemoveUnusedObjects 属性设为 false

删除 PDF 文档中的重复对象

合并 PDF 文档时,生成的 PDF 通常会包含重复的字体和图像。替换重复对象有助于减小生成的 PDF 文件大小。以下是此操作的 C# 示例:

using var pdf = new PdfDocument("merged.pdf");
pdf.ReplaceDuplicateObjects();

pdf.Save("compressed.pdf");

建议在压缩图像或取消嵌入字体之前先删除重复对象。否则,为优化相同图像或字体的副本会做很多额外工作。

PdfDocument.ReplaceDuplicateObjects 方法不会替换内联图像。如果文档包含内联图像,则请先使用 PdfCanvas.MoveInlineImagesToResources 方法。该方法会将内联图像转换为常规图像,然后 ReplaceDuplicateObjects 方法也可以对转换后的图像去重。

压缩 PDF 中的图像

对 PDF 图像进行优化通常是处理包含光栅图像文档时最有效的压缩方法。

Docotic.Pdf library 提供内置方法,可使用 JPEG、CCITT Group 3 和 4(传真)、JPEG 2000 以及 zip/deflate 压缩算法重新压缩 PDF 图像。你还可以调整图像大小或缩小采样,以进一步减小 PDF 文件大小。或者,你也可以先使用第三方工具自行优化图像,然后替换图像

查看 GitHub 上的 在 C# 和 VB.NET 中优化 PDF 文档中的图像 示例以了解具体示例。

字体子集化

PDF 文档通常会嵌入用于绘制文本的字体。嵌入字体通常包含关于所有受支持字形的信息。删除在 PDF 文档中未使用的字形可以显著减小输出文件大小。

此示例演示如何在 C# 中优化 PDF 字体:

using var pdf = new PdfDocument("text.pdf");
pdf.RemoveUnusedFontGlyphs();

pdf.Save("compressed.pdf");

子集化不会影响用于可变文本控件的字体,例如文本框或组合框。

删除元数据

PDF 文档可以包含未压缩的 XMP 元数据,其中包含作者、关键字、创建时间等信息。元数据不会影响 PDF 文档的可见内容。

此示例演示如何在 C# 中从 PDF 文件中删除元数据:

using var pdf = new PdfDocument("metadata.pdf");

XmpMetadata xmp = pdf.Metadata;
xmp.Unembed();
pdf.Info.Clear(false);

pdf.Save("compressed.pdf");

删除结构信息

PDF 文档可以包含有关其逻辑结构的信息。该信息用于:

  • 生成带标签的 PDF 文档
  • 使 PDF 文档可供辅助功能设备访问

删除此类信息有助于减小 PDF 文件大小。但 PDF 将不再带标签,也无法供辅助功能设备访问。此示例演示如何在 C# 中删除 PDF 中的结构信息:

using var pdf = new PdfDocument("tagged.pdf");
pdf.RemoveStructureInformation();

pdf.Save("compressed.pdf");

删除 PDF 中未使用的资源

PDF 页面和 XObject 可以引用比实际使用更多的字体、图像或图案。你可以使用 PdfDocument.RemoveUnusedResources 方法删除 PDF 中未使用的资源。以下是 C# 示例:

using var pdf = new PdfDocument("input.pdf");
pdf.RemoveUnusedResources();

pdf.Save("compressed.pdf");

删除 PDF 中的私有应用程序数据

由 Adobe 软件生成的 PDF 文档可以包含私有应用程序数据。这类应用程序数据存储在 page-piece 字典中。

此示例演示如何通过删除 page-piece 字典在 C# 中清理并压缩 PDF:

using var pdf = new PdfDocument("input.pdf");
pdf.RemovePieceInfo();

pdf.Save("compressed.pdf");

展平 PDF 表单字段和批注

你可以通过展平表单字段来减小已填写表单的 PDF 文档大小。展平会将表单字段替换为其视觉表示,已填写的值将被保留。此 C# 示例演示如何展平所有 PDF 表单字段:

using var pdf = new PdfDocument("form.pdf");
pdf.FlattenControls();

pdf.Save("compressed.pdf");

或者,你可以使用 PdfDocument.FlattenWidgets 方法展平所有批注和控件。

此外,PdfWidget.Flatten 方法允许你展平单个批注或控件。

取消嵌入字体

对自定义或稀有字体进行 PDF 字体嵌入非常合理。与此同时,Arial 或 Verdana 这类广泛可用的字体可能会在没有必要的情况下增加 PDF 文件大小。你可以取消嵌入目标平台上可用的常见字体。C# 示例代码:

using var pdf = new PdfDocument("input.pdf");
UnembedFonts(pdf);
pdf.Save("compressed.pdf");

/// <summary>
/// 此方法会取消嵌入满足以下条件的任何字体:
/// * 已安装在操作系统中
/// * 或其名称包含在 "always unembed" 列表中
/// * 且其名称不包含在 "always keep" 列表中。
/// </summary>
private static void UnembedFonts(PdfDocument pdf)
{
    string[] alwaysUnembedList = ["MyriadPro-Regular"];
    string[] alwaysKeepList = ["ImportantFontName", "AnotherImportantFontName"];

    using var ms = new MemoryStream();

    foreach (PdfFont font in pdf.GetFonts())
    {
        if (!font.Embedded ||
            font.EncodingName == "Built-In" ||
            Array.Exists(alwaysKeepList, name => font.Name == name))
        {
            continue;
        }

        if (font.Format == PdfFontFormat.TrueType || font.Format == PdfFontFormat.CidType2)
        {
            SystemFontLoader loader = SystemFontLoader.Instance;

            ms.Position = 0;
            if (loader.TryLoad(font.Name, font.Bold, font.Italic, ms))
            {
                font.Unembed();
                continue;
            }
        }

        if (Array.Exists(alwaysUnembedList, name => font.Name == name))
            font.Unembed();
    }
}

不要将此技术用于 PDF/A 文档。PDF/A 文档必须嵌入所有字体。

请务必在目标操作系统(Windows、Linux、macOS、iOS、Android)和 PDF 查看器(Adobe、Foxit 等)中测试取消嵌入字体的 PDF 文档。

其他减小 PDF 大小的方法

上面提到的优化方法很多。不过,你还可以通过删除不重要的内容进一步压缩 PDF 文档。Docotic.Pdf 允许你从 PDF 文档中删除这些对象:

  • 批注
  • 附件
  • 书签
  • 表单字段
  • 页面
  • 脚本
  • 透明度

你还可以从 PDF 页面中删除文本、图像和矢量图形。也可以进行文本展平。

结论

你可以使用 Docotic.Pdf library 在 C# 和 VB.NET 中压缩 PDF。Docotic.Pdf 提供了许多有效的优化手段。

从 GitHub 下载并试用完整的 在 C# 和 VB.NET 中压缩 PDF 文档 示例。

联系我们,我们会建议如何为你的 PDF 文档实现最佳压缩比。