1
votes

The code is below. It is adapted from a standard itext 7 example to add a PdfRedactAnnotation. The link annotation works, but the stamp and redact ones don't work. The PDF that I'm using is linked here. Anyone know why this won't work? Is is something about the PDF?

My end goal is to put some white rectangles over portions of the text so that the text doesn't show up when printing.

import java.io.File;
import java.nio.file.Paths;

import com.itextpdf.kernel.colors.ColorConstants;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfName;
import com.itextpdf.kernel.pdf.PdfNumber;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.action.PdfAction;
import com.itextpdf.kernel.pdf.annot.PdfAnnotation;
import com.itextpdf.kernel.pdf.annot.PdfLinkAnnotation;
import com.itextpdf.kernel.pdf.annot.PdfRedactAnnotation;
import com.itextpdf.kernel.pdf.annot.PdfStampAnnotation;

public class AddRotatedAnnotation {
    static final String SRC = Paths.get("calendar_2018-08-04_2018-08-19.pdf").toString();
    static final String DEST = Paths.get("calendar_clean.pdf").toString();


    public static void main(String[] args) throws Exception {
        File file = new File(DEST);
        file.getParentFile().mkdirs();
        new AddRotatedAnnotation().manipulatePdf(DEST);
    }

    protected void manipulatePdf(String dest) throws Exception {
        PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(DEST));

        PdfAction action = PdfAction.createURI("http://pages.itextpdf.com/ebook-stackoverflow-questions.html");
        Rectangle linkLocation1 = new Rectangle(30, 770, 90, 30);
        PdfAnnotation link1 = new PdfLinkAnnotation(linkLocation1)
                .setHighlightMode(PdfAnnotation.HIGHLIGHT_INVERT)
                .setAction(action)
                .setColor(ColorConstants.RED.getColorValue());
        pdfDoc.getFirstPage().addAnnotation(link1);

        Rectangle linkLocation2 = new Rectangle(30, 670, 30, 90);
        PdfAnnotation link2 = new PdfRedactAnnotation(linkLocation2)
                .setColor(ColorConstants.BLACK.getColorValue());
        pdfDoc.getFirstPage().addAnnotation(link2);

        Rectangle linkLocation3 = new Rectangle(150, 770, 90, 30);
        PdfAnnotation stamp1 = new PdfStampAnnotation(linkLocation3)
                .setStampName(new PdfName("Confidential"))
                .setContents("Landscape").setColor(ColorConstants.BLACK.getColorValue());
        pdfDoc.getFirstPage().addAnnotation(stamp1);

        Rectangle linkLocation4 = new Rectangle(150, 670, 90, 90);
        PdfAnnotation stamp2 = new PdfStampAnnotation(linkLocation4)
                .setStampName(new PdfName("Confidential"))
                .setContents("Portrait")
                .put(PdfName.Rotate, new PdfNumber(90));
        pdfDoc.getFirstPage().addAnnotation(stamp2);

        Rectangle linkLocation5 = new Rectangle(250, 670, 90, 90);
        PdfAnnotation stamp3 = new PdfStampAnnotation(linkLocation5)
                .setStampName(new PdfName("Confidential"))
                .setContents("Portrait")
                .put(PdfName.Rotate, new PdfNumber(45));
        pdfDoc.getFirstPage().addAnnotation(stamp3);

        pdfDoc.close();
    }
}
1
"but the stamp and redact ones don't work." - in which way don't they work? Does your program get stuck in that code? Does it throw some exception? Does the computer explode? - mkl
The stamp is not visible and the redact doesn't cover any text. - Jon

1 Answers

1
votes

By running the OP's code the problems are apparent:

  • in a PDF viewer the annotations are essentially transparent; depending on the viewer they can be selected or their pop-ups appear;
  • in a print-out the annotation are completely absent.

These issues can be fixed individually:

  • the annotations need appearance streams for normal display and
  • they need to have their respective PRINT flag set to be visible in print-outs.

I enhanced your annotations link2 and stamp1 accordingly as link2x and stamp1x:

Rectangle linkLocation2x = new Rectangle(150, 470, 30, 90);
PdfAnnotation link2x = new PdfRedactAnnotation(linkLocation2x)
        .setColor(ColorConstants.BLACK.getColorValue());
PdfFormXObject formN = new PdfFormXObject(linkLocation2x);
PdfCanvas canvasN = new PdfCanvas(formN, pdfDoc);
canvasN.setFillColorGray(1)
       .rectangle(linkLocation2x.getX(), linkLocation2x.getY(), linkLocation2x.getWidth(), linkLocation2x.getHeight())
       .fill();
link2x.setNormalAppearance(formN.getPdfObject());
link2x.setFlag(PdfAnnotation.PRINT);
pdfDoc.getFirstPage().addAnnotation(link2x);

Rectangle linkLocation3x = new Rectangle(150, 370, 90, 30);
PdfAnnotation stamp1x = new PdfStampAnnotation(linkLocation3x)
        .setStampName(new PdfName("Confidential"))
        .setContents("Landscape").setColor(ColorConstants.BLACK.getColorValue());
formN = new PdfFormXObject(linkLocation3x);
canvasN = new PdfCanvas(formN, pdfDoc);
canvasN.setFillColorGray(1)
       .rectangle(linkLocation3x.getX(), linkLocation3x.getY(), linkLocation3x.getWidth(), linkLocation3x.getHeight())
       .fill();
stamp1x.setNormalAppearance(formN.getPdfObject());
stamp1x.setFlag(PdfAnnotation.PRINT);
pdfDoc.getFirstPage().addAnnotation(stamp1x);

If you did this not only for printing but also for distribution of the electronic PDF, you should add redaction annotations and then run redaction, e.g. using the iText 7 pdfSweep add-on, to actually remove that information and not merely cover it.