FindAndRedact.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.IO;
  6. using System.Drawing;
  7. using System.Text.RegularExpressions;
  8. using GrapeCity.Documents.Pdf;
  9. using GrapeCity.Documents.Pdf.Annotations;
  10. using GrapeCity.Documents.Pdf.TextMap;
  11. using GrapeCity.Documents.Pdf.AcroForms;
  12.  
  13. namespace DsPdfWeb.Demos
  14. {
  15. // This sample shows how to use the text map to find specific content
  16. // in a PDF and mark it for redaction.
  17. // Check out the ApplyRedact sample to see how the redact annotations
  18. // added by this sample can be applied to actually erase the data.
  19. // Also check out the samples in DsPdfViewer section to see how
  20. // redact annotations (added programmatically as in this sample,
  21. // or via the viewer's UI) can be applied selectively or all together.
  22. // The PDF used in this sample was created by TimeSheet.
  23. public class FindAndRedact
  24. {
  25. public int CreatePDF(Stream stream)
  26. {
  27. var doc = new GcPdfDocument();
  28. using var fs = File.OpenRead(Path.Combine("Resources", "PDFs", "TimeSheet.pdf"));
  29. doc.Load(fs);
  30.  
  31. // Note: Acrobat does not allow applying redactions in a digitally signed
  32. // document, so first we find and remove any existing signatures:
  33. removeSignatureFields(doc.AcroForm.Fields);
  34.  
  35. // Loop through pages, removing anything that looks like a short date:
  36. foreach (var page in doc.Pages)
  37. {
  38. var tmap = page.GetTextMap();
  39. foreach (ITextLine tline in tmap)
  40. {
  41. if (Regex.Match(tline.Text.Trim(), @"\d+[/-]\w+[/-]\d").Success)
  42. {
  43. var redact = new RedactAnnotation()
  44. {
  45. Rect = tline.GetCoords().ToRect(),
  46. MarkBorderColor = Color.Red,
  47. MarkFillColor = Color.Yellow,
  48. Page = page
  49. };
  50. // If we hadn't already set redact.Page = page, we could do this:
  51. // page.Annotations.Add(redact);
  52. }
  53. }
  54. }
  55. // Done:
  56. doc.Save(stream);
  57. return doc.Pages.Count;
  58.  
  59. // This code is from the RemoveSignatureFields sample:
  60. static void removeSignatureFields(FieldCollection fields)
  61. {
  62. for (int i = fields.Count - 1; i >= 0; --i)
  63. {
  64. removeSignatureFields(fields[i].Children);
  65. if (fields[i] is SignatureField)
  66. fields.RemoveAt(i);
  67. }
  68. }
  69. }
  70.  
  71. // Viewer options for SupportApiDemo:
  72. public static GcPdfViewerSupportApiDemo.Models.PdfViewerOptions PdfViewerOptions
  73. {
  74. get => new GcPdfViewerSupportApiDemo.Models.PdfViewerOptions(
  75. GcPdfViewerSupportApiDemo.Models.PdfViewerOptions.Options.AnnotationEditorPanel |
  76. GcPdfViewerSupportApiDemo.Models.PdfViewerOptions.Options.ActivateAnnotationEditor,
  77. viewerTools: new string[] { "save", "edit-redact-apply", "$split", "text-selection", "pan", "$zoom", "$fullscreen", "print", "rotate", "download", "doc-properties", "about" },
  78. annotationEditorTools: new string[] { "save", "edit-redact", "edit-redact-apply" });
  79. }
  80. }
  81. }
  82.