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

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

在许多情况下,压缩和优化 PDF 文档是一种普遍的愿望。 较小的 PDF 文档更容易通过网络传输且存储成本更 低。 减小 PDF 文件大小对于归档目的尤其重要。

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

用于优化 PDF 文档的 .NET 库

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

Docotic.Pdf 库 9.5.17664-dev 回归测试 14,820 通过 NuGet 总下载量 4,998,853

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 库提供了使用 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 文档可以包含私有应用程序数据。 此类应用程序数据存储在页片字典中。

此示例展示了如何通过删除页片字典来在 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>
/// 此方法取消嵌入任何字体:
/// * 安装在操作系统中
/// * 或者其名称包含在“始终不嵌入”列表中
/// * 并且其名称不包含在“始终保留”列表中。
/// </summary>
private static void unembedFonts(PdfDocument pdf)
{
    string[] alwaysUnembedList = new string[] { "MyriadPro-Regular" };
    string[] alwaysKeepList = new string[] { "ImportantFontName", "AnotherImportantFontName" };

    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;
            byte[] fontBytes = loader.Load(font.Name, font.Bold, font.Italic);
            if (fontBytes != null)
            {
                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 库 在 C# 和 VB.NET 中压缩 PDF。 Docotic.Pdf提供了许多有效 的优化手段。

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

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