Customizing redaction with pdfSweep

Tags: pdfSweepredactredactionremove from PDFremove textpdfSweep example

With pdfSweep it is also easy to customize your redaction process. This example shows you how to change the color of the redaction annotation to match the color of the text that was redacted, to provide a more aesthetically pleasing result.

We start by defining a class that extends CharacterRenderInfo, and keeps tracks of the color of each character.

  1. class CCharacterRenderInfo extends CharacterRenderInfo {
  2.  
  3. private Color strokeColor;
  4. private Color fillColor;
  5.  
  6. public CCharacterRenderInfo(TextRenderInfo tri) {
  7. super(tri);
  8. this.strokeColor = tri.getStrokeColor();
  9. this.fillColor = tri.getFillColor();
  10. }
  11.  
  12. public Color getStrokeColor() {
  13. return strokeColor;
  14. }
  15.  
  16. public Color getFillColor() {
  17. return fillColor;
  18. }
  19. }

This class can then be used to build a custom strategy, that knows the color of the redacted elements.

  1. class CustomLocationExtractionStrategy extends RegexBasedLocationExtractionStrategy implements ICleanupStrategy {
  2.  
  3. private String regex;
  4. private Map<Rectangle, Color> colorByRectangle = new HashMap<>();
  5.  
  6. public CustomLocationExtractionStrategy(String regex) {
  7. super(regex);
  8. this.regex = regex;
  9. }
  10.  
  11. @Override
  12. public List<CharacterRenderInfo> toCRI(TextRenderInfo tri) {
  13. List<CharacterRenderInfo> cris = new ArrayList<>();
  14. for (TextRenderInfo subTri : tri.getCharacterRenderInfos()) {
  15. cris.add(new CCharacterRenderInfo(subTri));
  16. }
  17. return cris;
  18. }
  19.  
  20. @Override
  21. public List<Rectangle> toRectangles(List<CharacterRenderInfo> cris) {
  22. Color col = ((CCharacterRenderInfo) cris.get(0)).getFillColor();
  23. List<Rectangle> rects = new ArrayList<>(super.toRectangles(cris));
  24. for (Rectangle rect : rects) {
  25. colorByRectangle.put(rect, col);
  26. }
  27. return rects;
  28. }
  29.  
  30. @Override
  31. public Color getRedactionColor(IPdfTextLocation rect) {
  32. return colorByRectangle.containsKey(rect.getRectangle()) ? colorByRectangle.get(rect.getRectangle()) : Color.BLACK;
  33. }
  34.  
  35. public ICleanupStrategy reset() {
  36. return new CustomLocationExtractionStrategy(regex);
  37. }
  38. }

The custom strategy can easily be called with following code:

  1. // load license key
  2. LicenseKey.loadLicenseFile(licenceFile);
  3.  
  4. String input = "iphone_user_guide_untagged.pdf";
  5. String output = "redactIPhoneUserManualMatchColor.pdf";
  6.  
  7. CompositeCleanupStrategy strategy = new CompositeCleanupStrategy();
  8. strategy.add(new CustomLocationExtractionStrategy("(iphone)|(iPhone)"));
  9.  
  10. PdfDocument pdf = new PdfDocument(new PdfReader(input), new PdfWriter(output));
  11.  
  12. // sweep
  13. PdfAutoSweep autoSweep = new PdfAutoSweep(strategy);
  14. autoSweep.cleanUp(pdf);
  15. pdf.close();

This is what the example output document looks like, post redaction:

Custom redaction with pdfSweep
Custom redaction with pdfSweep