該頁面可以包含自動翻譯的文字。

在 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 提供多種不同的最佳化方式:

  • 最佳化 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(fax)、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 文件可能包含其邏輯結構的資訊。該資訊用於:

  • 產生 Tagged PDF 文件
  • 讓 PDF 文件可供輔助裝置存取

移除此類資訊有助於減少 PDF 檔案大小。但 PDF 將不再具有標籤,且也無法供輔助裝置存取。此範例示範如何從 PDF 中刪除結構資訊:

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

pdf.Save("compressed.pdf");

移除 PDF 中未使用的資源

PDF 頁面和 XObjects 可能參照比實際使用更多的字型、影像或樣式。您可以使用 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 函式庫 在 C# 和 VB.NET 中壓縮 PDF。Docotic.Pdf 提供許多有效的最佳化方式。

從 GitHub 下載並試用完整的 在 C# 和 VB.NET 中壓縮 PDF 文件 範例。

聯絡我們,我們將建議如何為您的 PDF 文件達到最佳壓縮比。