RemoveDuplicateImages.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.Drawing;
  8. using GrapeCity.Documents.Pdf;
  9. using GrapeCity.Documents.Pdf.Annotations;
  10. using System.Collections.Generic;
  11.  
  12. namespace DsPdfWeb.Demos
  13. {
  14. // When merging PDFs that contain identical images, by default the resulting PDF
  15. // will end up containing several copies of the same image.
  16. // To ensure that the PDF is not larger than necessary, DsPdf provides the method
  17. // GcPdfDocument.RemoveDuplicateImages() that scans the PDF, finds and removes duplicates.
  18. // The MergeDocumentOptions class also has the property RemoveDuplicateImages,
  19. // which allows you to scan for/remove duplicates at once when merging PDFs,
  20. // but by default it is false. This is because the occurrence of duplicate images
  21. // in merged PDFs is not a very common scenario, while scanning for duplicates
  22. // may affect the performance of the merge. Also, if you are merging multiple PDFs
  23. // that contain duplicate images, it is better to merge all PDFs first, and then
  24. // remove all duplicates from the final PDF at once with a single call to
  25. // GcPdfDocument.RemoveDuplicateImages(), as demonstrated by this demo.
  26. //
  27. // In this demo we merge several sample invoices that include the same company logo,
  28. // and then call GcPdfDocument.RemoveDuplicateImages() and compare the sizes of the
  29. // resulting PDF before and after that call.
  30. //
  31. // See also OptimizeFonts.
  32. public class RemoveDuplicateImages
  33. {
  34. static FileStream MergePDFs(GcPdfDocument dest, string fpath)
  35. {
  36. GcPdfDocument d = new GcPdfDocument();
  37. var fs = File.OpenRead(fpath);
  38. d.Load(fs);
  39. dest.MergeWithDocument(d);
  40. return fs;
  41. }
  42.  
  43. public int CreatePDF(Stream stream)
  44. {
  45. // Input file names:
  46. const int N = 7;
  47. var fpaths = new List<string>(N);
  48. for (int i = 1; i <= 7; i++)
  49. fpaths.Add(Path.Combine("Resources", "PDFs", $"DsDemoInvoice{i}.pdf"));
  50. // Facilitate clean up:
  51. var fss = new List<FileStream>();
  52. string tempPdfBefore = null, tempPdfAfter = null;
  53. try
  54. {
  55. var doc = new GcPdfDocument();
  56. // Merge the invoices into a single PDF:
  57. for (int i = 0; i < N; i++)
  58. fss.Add(MergePDFs(doc, fpaths[i]));
  59.  
  60. // Compare the merged PDF size before and after removing duplicates:
  61. tempPdfBefore = Path.GetTempFileName();
  62. doc.Save(tempPdfBefore);
  63. var sizeBefore = new FileInfo(tempPdfBefore).Length;
  64. doc.RemoveDuplicateImages();
  65. tempPdfAfter = Path.GetTempFileName();
  66. doc.Save(tempPdfAfter);
  67. var sizeAfter = new FileInfo(tempPdfAfter).Length;
  68. Common.Util.AddNote(String.Format(
  69. "Using the GcPdfDocument.RemoveDuplicateImages() method on this document (which was produced by merging " +
  70. "several demo invoices with the same company logo) reduced the size of the merged PDF from {0:N0} to {1:N0} bytes.",
  71. sizeBefore, sizeAfter),
  72. doc.Pages.Insert(0));
  73. doc.Save(stream);
  74. return doc.Pages.Count;
  75. }
  76. finally
  77. {
  78. if (tempPdfBefore != null)
  79. File.Delete(tempPdfBefore);
  80. if (tempPdfAfter != null)
  81. File.Delete(tempPdfAfter);
  82. fss.ForEach(fs_ => fs_.Dispose());
  83. }
  84. }
  85. }
  86. }
  87.