Skip to content

Commit

Permalink
GH-314 headless redaction example
Browse files Browse the repository at this point in the history
  • Loading branch information
Patrick Corless committed Feb 11, 2024
1 parent 2baaccb commit 48d45bf
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 1 deletion.
1 change: 1 addition & 0 deletions examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<module>loadingEvents</module>
<module>printservices</module>
<module>search</module>
<module>redaction</module>
<module>signatures</module>
</modules>

Expand Down
13 changes: 13 additions & 0 deletions examples/redaction/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
plugins {
id 'java'
id 'application'
}

dependencies {
implementation project(':core:core-awt'), project(':viewer:viewer-awt')
}

description 'java redaction example'

mainClassName = "org.icepdf.examples.redaction.RedactionHeadless"
applicationDefaultJvmArgs = ["-Xms64m", "-Xmx1024m"]
22 changes: 22 additions & 0 deletions examples/redaction/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.icepdf.examples</groupId>
<artifactId>examples</artifactId>
<version>7.2.0-SNAPSHOT</version>
</parent>
<artifactId>redaction</artifactId>
<packaging>pom</packaging>
<name>ICEpdf :: Examples :: Redaction</name>
<description>
The ICEpdf redaction examples
</description>

<modules>
<module>component</module>
<module>headless</module>
</modules>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package org.icepdf.examples.redaction;

import org.icepdf.core.pobjects.Document;
import org.icepdf.core.pobjects.Page;
import org.icepdf.core.pobjects.annotations.Annotation;
import org.icepdf.core.pobjects.annotations.AnnotationFactory;
import org.icepdf.core.pobjects.annotations.RedactionAnnotation;
import org.icepdf.core.pobjects.graphics.text.WordText;
import org.icepdf.core.search.DocumentSearchController;
import org.icepdf.core.util.updater.WriteMode;
import org.icepdf.ri.common.search.DocumentSearchControllerImpl;
import org.icepdf.ri.util.FontPropertiesManager;

import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Collections;

/**
* The <code>RedactionHeadless</code> class is an example of how to use text search results
* as inputs for the creation of redaction annotations. Once the annotations are created the
* document is exported burning the redaction annotations into the PDFs content streams.
* The resulting document will no longer have text where the Redaction annotations intersected.
*
* @since 7.2.0
*/
public class RedactionHeadless {
public static void main(String[] args) {

FontPropertiesManager.getInstance().loadOrReadSystemFonts();

// Get a file from the command line to open
String filePath = args[0];

// save page captures to file.
float scale = 1.0f;
float rotation = 0f;

// open the document
Document document = new Document();
try {
document.setFile(filePath);

// get the search controller
DocumentSearchController searchController =
new DocumentSearchControllerImpl(document);
// add a specified search terms.
searchController.addSearchTerm("redaction", false, false);

ArrayList<WordText> foundWords;
RedactionAnnotation redactionAnnotation;

// iterated over each page creating redaction from search terms
for (int i = 0, max = document.getNumberOfPages(); i < max; i++) {
Page page = document.getPageTree().getPage(i);
page.init();

// search the page
foundWords = searchController.searchPage(i);
if (foundWords == null) {
System.out.println("No Search terms found");
return;
}
for (WordText wordText : foundWords) {
final Rectangle tBbox = wordText.getBounds().getBounds();

redactionAnnotation = (RedactionAnnotation)
AnnotationFactory.buildAnnotation(
document.getPageTree().getLibrary(),
Annotation.SUBTYPE_REDACT,
tBbox);

if (redactionAnnotation != null) {
redactionAnnotation.setColor(Color.BLACK);
redactionAnnotation.setMarkupBounds(new ArrayList<>(Collections.singletonList(tBbox)));
redactionAnnotation.setMarkupPath(new GeneralPath(tBbox));
redactionAnnotation.setBBox(tBbox);
redactionAnnotation.resetAppearanceStream(new AffineTransform());
page.addAnnotation(redactionAnnotation, true);
}
}
}

// burn the redaction into the PDF by exporting the document.
File file = new File("redacted_output.pdf");
try (final FileOutputStream fileOutputStream = new FileOutputStream(file);
final BufferedOutputStream buf = new BufferedOutputStream(fileOutputStream, 8192)) {
document.writeToOutputStream(buf, WriteMode.FULL_UPDATE);
}

// clean up resources
document.dispose();

} catch (Exception e) {
e.printStackTrace();
}
}

}
5 changes: 4 additions & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,7 @@ include 'core:core-awt',
'examples:signatures'


rootProject.name = 'icepdf'
rootProject.name = 'icepdf'
include 'examples:redaction'
findProject(':examples:redaction')?.name = 'redaction'

0 comments on commit 48d45bf

Please sign in to comment.