Merge duplicate and remove unused fonts in a PDF

PDF TIFF SVG JPG C# VB
OptimizeFonts.cs
  1. //
  2. // This code is part of Document Solutions for PDF demos.
  3. // Copyright (c) MESCIUS inc. All rights reserved.
  4. //
  5. using System;
  6. using System.IO;
  7. using System.IO.Compression;
  8. using System.Drawing;
  9. using System.Collections.Generic;
  10. using GrapeCity.Documents.Pdf;
  11. using GrapeCity.Documents.Text;
  12. using GrapeCity.Documents.Common;
  13.  
  14. namespace DsPdfWeb.Demos
  15. {
  16. // This sample shows how the GcPdfDocument.OptimizeFonts() method can be used
  17. // to reduce the size of a PDF by merging duplicate and removing unused embedded fonts.
  18. //
  19. // This sample extracts the first five pages of a PDF, and then merges those pages
  20. // into a single new document. Because each page has its own set of embedded fonts,
  21. // the created PDF contains redundant font data, resulting in excessive file size.
  22. // The sample records the merged PDF's size, then it runs OptimizeFonts() on that PDF
  23. // and records the size of the optimized PDF. These results are printed into the
  24. // PDF returned by the sample, thus illustrating the effect of running OptimizeFonts().
  25. //
  26. // Note that while in this sample the PDF being optimized is somewhat contrived,
  27. // similar PDFs do appear in real life applications. The OptimizeFonts()
  28. // method may reduce (sometimes significantly) the size of such PDFs.
  29. // Actual results will vary.
  30. //
  31. // See also RemoveDuplicateImages.
  32. public class OptimizeFonts
  33. {
  34. public int CreatePDF(Stream stream)
  35. {
  36. // Create a 5 page non-optimal PDF:
  37. var srcFn = Path.Combine("Resources", "PDFs", "CompleteJavaScriptBook.pdf");
  38. var tmpInput = MakeInputFile(srcFn);
  39. var fiInput = new FileInfo(tmpInput);
  40.  
  41. // Create a new PDF, load the source PDF into it, and optimize it:
  42. var tmpOutput = Path.GetTempFileName();
  43. var tmpDoc = new GcPdfDocument();
  44. using (var fs = File.OpenRead(tmpInput))
  45. {
  46. tmpDoc.Load(fs);
  47. // By default GcPdfDocument uses CompressionLevel.Fastest when saving a PDF.
  48. // If PDF size is important, we should use optimal compression:
  49. tmpDoc.CompressionLevel = CompressionLevel.Optimal;
  50. tmpDoc.OptimizeFonts();
  51. tmpDoc.Save(tmpOutput);
  52. }
  53. var fiOutput = new FileInfo(tmpOutput);
  54.  
  55. // Record the input and output file sizes in the resultant PDF:
  56. var doc = new GcPdfDocument();
  57. Common.Util.AddNote(String.Format(
  58. "Using the GcPdfDocument.OptimizeFonts() method reduced the size of a 5-page PDF from {0:N0} to {1:N0} bytes " +
  59. "by merging duplicate and removing unused font data.\n" +
  60. "To reproduce these results locally, download and run this sample. You may also modify the sample code to keep the temporary " +
  61. "input and output files and compare their sizes using a file manager.", fiInput.Length, fiOutput.Length),
  62. doc.NewPage());
  63. doc.Save(stream);
  64.  
  65. // Clean up:
  66. File.Delete(tmpInput);
  67. File.Delete(tmpOutput);
  68.  
  69. return doc.Pages.Count;
  70. }
  71.  
  72. static string MakeInputFile(string inFn)
  73. {
  74. var indoc = new GcPdfDocument();
  75. using var fs = File.OpenRead(inFn);
  76. indoc.Load(fs);
  77.  
  78. // Create 5 PDFs from the first 5 pages of the source document:
  79. var pageCount = 5;
  80. var docs = new List<GcPdfDocument>(pageCount);
  81. for (int i = 0; i < pageCount; ++i)
  82. {
  83. var outdoc = new GcPdfDocument();
  84. outdoc.MergeWithDocument(indoc, new MergeDocumentOptions() { PagesRange = new OutputRange(i + 1, i + 1) });
  85. docs.Add(outdoc);
  86. }
  87. // Merge the PDFs into a single document:
  88. var doc = new GcPdfDocument();
  89. foreach (var d in docs)
  90. doc.MergeWithDocument(d);
  91.  
  92. // Save the resultant PDF in a temp file:
  93. var outFn = Path.GetTempFileName();
  94. doc.Save(outFn);
  95. return outFn;
  96. }
  97. }
  98. }
  99.