0
votes

the title says it all, I am able to visually sign a pdf using pdfbox version 2.0.8. Currently I have to hard-code the starting coordination of image in code. but as PDFs varies position of image always needs to be changed accordingly. I want to apply signature image at the end of pdf in left corner. how do I get that position in code? here is my code, hard coding coordinates using _x & _y. In code 'signing' is visible signature object and 'page' is the last page of pdf, 'args[2]' is pdf-file to be signed:

int _x = 30;
int _y = 420;
signing.setVisibleSignDesigner(args[2], _x, _y, -50, imageStream, page);
imageStream.close();
signing.setExternalSigning(externalSig);
signing.signPDF(documentFile, signedDocumentFile, tsaClient);
removeFile(imageResult);

Example of Signature I want:

Example of Signature I want

Edit: added Image to clarify that I want signature field to be at the end of document, not at the end of last page. document may be completed at the top of the last page so field should also be right after the text not at the end of the page. sorry I wasn't clear with my question earlier.

1
The bottom left is (0,0), did you try that? The current PDFBox version is 2.0.17.Tilman Hausherr
@TilmanHausherr The bottom left is (0,0) - for the target page coordinates that is not necessarily the case. Or does VisibleSignature and the VisibleSignDesigner normalize that away?mkl
@mkl if you mean rotation, there is a method PDVisibleSignDesigner.adjustForRotation() which was inspired by an answer by you.Tilman Hausherr
@TilmanHausherr "if you mean rotation" - No, I was thinking of document pages with crop boxes which do not have the origin in their lower left corner.mkl
So you essentially look for the bounding box of existing contents of that page. You can see how to determine that bounding box in this answer. Simply determine the bounding box as explained there and position the signature right underneath.mkl

1 Answers

1
votes

According to the clarifications in comments to the question, you try to position the signature right underneath the bounding box of existing contents of the last document page.

To determine that bounding box you can use the BoundingBoxFinder presented in this answer.

But as you found out in response to a comment to that effect, you cannot simply use its result as input for CreateVisibleSignature.setVisibleSignDesigner as different coordinate systems are assumed:

  • The BoundingBoxFinder uses the PDF default user space coordinates of the page in question: They are given by the MediaBox of the page in question and have their y coordinates increase upwards. Usually the origin is in the lower left corner of the page.
  • CreateVisibleSignature on the other hand uses a coordinate system with the same unit length but having the origin in the upper left corner of the page and the y coordinates increasing downwards.

Thus, the coordinates have to be transformed, e.g. like this:

File documentFile = new File(SOURCE);
File signedDocumentFile = new File(RESULT);

Rectangle2D boundingBox;
PDRectangle mediaBox;
try (   PDDocument document = PDDocument.load(documentFile) ) {
    PDPage pdPage = document.getPage(0);
    BoundingBoxFinder boundingBoxFinder = new BoundingBoxFinder(pdPage);
    boundingBoxFinder.processPage(pdPage);
    boundingBox = boundingBoxFinder.getBoundingBox();
    mediaBox = pdPage.getMediaBox();
}

CreateVisibleSignature signing = new CreateVisibleSignature(ks, PASSWORD.clone());
try (   InputStream imageStream = IMAGE_STREAM) {
    signing.setVisibleSignDesigner(documentFile.getPath(), (int)boundingBox.getX(), (int)(mediaBox.getUpperRightY() - boundingBox.getY()), -50, imageStream, 1);
}
signing.setVisibleSignatureProperties("name", "location", "Security", 0, 1, true);
signing.setExternalSigning(false);
signing.signPDF(documentFile, signedDocumentFile, null);

(CreateSignature test signLikeHemantPdfTest)

Remarks

I found a document looking like your Yukon Education PDF Test File here. Applying the code above to that file, one observes that there is a small gap between the last visible line of text and the image. This gap is caused by some space characters in a line below the "Please visit our website" line. The BoundingBoxFinder does not check whether a drawing instruction eventually results in something visible, it always adds the area in question to the bounding box.

In general you may want to subtract a small bit from the y coordinate calculated by the code above to create a visual gap between former page content and the new signature widget.

Looking into the sources of the CreateVisibleSignature one sees that there actually the y coordinates are transformed by subtracting them from the height of the MediaBox, not from its upper border value. Eventually these coordinates are copied into the target document. Thus, it may be necessary to use mediaBox.getHeight() instead of mediaBox.getUpperRightY() in the code above.

Looking into the sources of the CreateVisibleSignature2 one sees that there actually the CropBox is used instead of the MediaBox. If your code derives from that example, you may have to replace pdPage.getMediaBox() by pdPage.getCropBox() in the code above.

In general this arbitrary use of different coordinate systems is one of the fairly few sources of irritation when working with PDFBox.