maht33n
maht33n

Reputation: 35

PDFBox: Loading an Image Into PDF From a JAR Resource

Good afternoon. I have a JAR file to which I have attached some images as resources in a folder called logos. I am being told to do this due to security restrictions (we don't want the image files to be exposed in the same folder as the JAR). I first tried to load these images in as if they were a File object, but that obviously doesn't work. I am now trying to use an InputStream to load the image into the required PDImageXObject, but the images are not rendering into the PDF. Here is a snippet of the code which I am using:

String logoName = "aLogoName.png";
PDDocument document = new PDDocument(); 

// the variable "generator" is an object used for operations in generating the PDF
InputStream logoFileAsStream = generator.getClass().getResourceAsStream("/" + logoName);
PDStream logoStream = new PDStream(document, logoFileAsStream);
PDImageXObject logoImage = new PDImageXObject(logoStream, new PDResources());

PDPage page = new PDPage(new PDRectangle(PDRectangle.A4.getHeight(), PDRectangle.A4.getWidth()));
document.addPage(page);
PDPageContentStream contentStream = new PDPageContentStream(document, page);
contentStream.drawImage(logoImage, 500, 100);

Note that I have verified that the resource is getting loaded in correctly, as using logoFileAsStream.available() returns a different value for various logos. After running this code, the image does not actually get drawn on the PDF, and upon opening it, the error message "An error exists on this page. Acrobat may not display the page correctly. Please contact the person who created the PDF document to correct the problem." appears. Could someone please help me figure what's wrong with that code snippet/a different solution to load my images in as a resource from the JAR? Thanks so much. Let me know if more details are needed/clarification.

Upvotes: 1

Views: 1387

Answers (1)

Tilman Hausherr
Tilman Hausherr

Reputation: 18851

This PDImageXObject constructor is for internal PDFBox use only. You can use

PDImageXObject.createFromByteArray(document, IOUtils.toByteArray(logoFileAsStream), logoName /* optional, can be null */)

for maximum flexibility, or if you know it is always a PNG file

LosslessFactory.createFromImage(document, ImageIO.read(logoFileAsStream))

don't forget to close logoFileAsStream and contentStream.

Upvotes: 2

Related Questions