Unable to Insert image from classpath into PDF using PDFBox - java

I have a springBoot project and i am trying to insert an image into PDF using PDFBox library. The image is present in src/main/resources/image folder (myImage.jpg). The implementation code is as given below. While running the program i am getting an error that image is not found at specified path. What is the correct way to retrieve the image from classpath in this scenario.
public class PDFImageService {
public void insertImage() throws IOException {
//Loading an existing document
File file = new File("/eclipse-workspace/blank.pdf");
PDDocument doc = PDDocument.load(file);
//Retrieving the page
PDPage page = doc.getPage(1);
//Creating PDImageXObject object
PDImageXObject pdImage = PDImageXObject.createFromFile("/image/myImage.jpg",doc);
//creating the PDPageContentStream object
PDPageContentStream contents = new PDPageContentStream(doc, page);
//Drawing the image in the PDF document
contents.drawImage(pdImage, 250, 300);
System.out.println("Image inserted Successfully.");
//Closing the PDPageContentStream object
contents.close();
//Saving the document
doc.save("/eclipse-workspace/blank.pdf");
//Closing the document
doc.close();
}
}
It works fine if i give the fully specified image path as
PDImageXObject pdImage = PDImageXObject.createFromFile("C:\Users\Dell\Desktop\PDF\myImage.jpg",doc);

As discussed in the comments, it works by using
PDImageXObject img;
try (InputStream is = PDFImageService.class.getResourceAsStream("/image/myImage.jpg");
{
// check whether InputStream is null omitted
byte [] ba = IOUtils.toByteArray(imageAsStream);
img = PDImageXObject.createFromByteArray(document, ba, "myImage.jpg");
}

Unless eclipse-workspace folder is on / (root) the top file in the OS then it would be implicit and incorrectly stated, when you installed configured eclipse it usually asserts the user home folder to put workspace into. If it is on root / then i suggest you add a FileNotFoundException before the IOException.

Related

itext 7 (java) add image on a new page to the end of an existing pdf document

i'm new to itext 7. I have a list of documents with different content that I want to merge into a single PDF. The content types are PDF, JPG & PNG.
My problem is that as soon as I merge a PDF and an image, the image is written over the already inserted content of the target PDF.
How do I get each image to be added to a new page of the target PDF?
This is my Code:
byte[] mergeInhalt(List<Dokument> dokumentList) throws IOException {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
PdfWriter pdfWriter = new PdfWriter(byteOut);
PdfDocument pdfDocument = new PdfDocument(pdfWriter);
Document completeDocument = new Document(pdfDocument);
for (Dokument dokument : dokumentList) {
byte[] inhalt = dokument.getInhalt();
if (Objects.nonNull(inhalt)) {
switch (dokument.getFormat().name()) {
case "PDF":
addPdf(pdfDocument, inhalt);
break;
case "JPG":
case "PNG":
ImageData data = ImageDataFactory.create(inhalt);
Image image = new Image(data);
completeDocument.add(image);
break;
}
}
}
completeDocument.close();
return byteOut.toByteArray();
}
private void addPdf(PdfDocument pdfDocument, byte[] inhalt) throws IOException {
PdfReader pdfReader = new PdfReader(new ByteArrayInputStream(inhalt));
PdfDocument pdfDocumentToMerge = new PdfDocument(pdfReader);
pdfDocumentToMerge.copyPagesTo(1, pdfDocumentToMerge.getNumberOfPages(), pdfDocument);
}
Merging PDFs only works well, but everytime i merge a Image i get this:
The image with the pink one was placed over the text of the previous PDF
In your code you add the image via the Document completeDocument but you add the pdf via the underlying PdfDocument pdfDocument. Thus, the completeDocument doesn't know about the added pdf, continues on its current page, and draws over the imported pages.
To make sure each image is added on a new page after the currently last one, you have to tell completeDocument to move its current page:
case "JPG":
case "PNG":
ImageData data = ImageDataFactory.create(inhalt);
Image image = new Image(data);
completeDocument.add(new AreaBreak(AreaBreakType.LAST_PAGE));
completeDocument.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
completeDocument.add(image);
break;
For an example compare the tests testMergeLikeAndreasHuber and testMergeLikeAndreasHuberImproved in CopyPdfsAndImages and their outputs.

Barcode in PDF not displaying in FireFox [duplicate]

I am running into strange issue with generated pdf's from iText7. The generated pdf's are opening properly in Adobe reader and Chrome browser. But the same pdf is opening partially in the Firefox browser. I am getting the below message in Firefox. The strange thing is other pdf, which are not generated via iText are properly rendering in firefox.
Java code
public static byte[] createPdf(List<String> htmlPages, PageSize pageSize, boolean rotate) throws IOException {
ConverterProperties properties = new ConverterProperties();
// Register classpath protocol handler to be able to load HTML resources from class patch
org.apache.catalina.webresources.TomcatURLStreamHandlerFactory.register();
properties.setBaseUri("classpath:/");
// properties.setBaseUri(baseUri);
FontProvider fontProvider = new DefaultFontProvider(true,false,false);
properties.setFontProvider(fontProvider);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PdfDocument pdf = new PdfDocument(new PdfWriter(byteArrayOutputStream));
PdfMerger merger = new PdfMerger(pdf);
for (String htmlPage : htmlPages) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfDocument temp = new PdfDocument(new PdfWriter(baos));
if(rotate) {
temp.setDefaultPageSize(pageSize.rotate()); /** Page Size and Orientation */
} else {
temp.setDefaultPageSize(pageSize); /** Page Size and Orientation */
}
HtmlConverter.convertToPdf(htmlPage, temp, properties);
temp = new PdfDocument(new PdfReader(new ByteArrayInputStream(baos.toByteArray())));
merger.merge(temp, 1, temp.getNumberOfPages());
temp.close();
}
pdf.close();
byteArrayOutputStream.flush(); // Tried this
byteArrayOutputStream.close(); // Tried this
byte[] byteArray = byteArrayOutputStream.toByteArray();
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
try (FileOutputStream fileOuputStream = new FileOutputStream("D:\\Labels\\Label_"+timestamp.getTime()+".pdf")){
fileOuputStream.write(byteArray);
}
return byteArray;
}
Thanks in advance.
Edit 1:
You can find pdf and html/css for reproducing issue here.
When you embedded the images into your html using base64 URIs, something weird happened to the image of the barcode: Instead of the 205×59 bitmap image in labelData/barcode.png you embedded a 39578×44 image! (Yes, an image nearly a thousand times wider than high...)
The iText HtmlConverter embedded that image just fine but apparently Firefox has issues displaying an image with those dimensions even though (or probably because?) it is transformed into the desired dimensions (about four times wider than high) on the label. At least my Firefox installation stops drawing label contents right here. (Beware, the order of drawing in the PDF content is not identical to the of the HTML elements; in particular in the PDF the number 3232000... is drawn right before the barcode, not afterwards!)
On Firefox:
On Acrobat Reader:
Thus, you may want to check the transformation of the bar code image to the base64 image URI in your HTML file.

Problem drawing some 16bit transparent images with PDPageContentStream.drawImage after updating PDFBox from Version 2.08 to 2.12/2.16

I've some very basic code which inserts an image into an existing PDF:
public class InsertImg
{
public static void main (final String[] args) throws IOException
{
PDDocument document = PDDocument.load (new File ("original.pdf"));
PDPage page = document.getPage (0);
byte[] imgBytes = Files.readAllBytes (Paths.get ("signature.png"));
PDImageXObject pdImage = PDImageXObject.createFromByteArray (document, imgBytes, "name_of_image");
PDPageContentStream content = new PDPageContentStream (document, page, AppendMode.APPEND, true, true);
content.drawImage (pdImage, 50.0f, 350.0f, 100.0f, 25.0f);
content.close ();
document.save (new File ("result.pdf"));
document.close ();
}
}
While this code worked fine in PdfBox 2.08 for all image files, it works under version 2.012 only for some images and does not work anymore for all image files.
(Background: We would like to insert an image of a signature into an existing and already generated letter. The signatures are all generated with the same software. In version 2.12 not all signatures can be inserted anymore. In version 2.08 all signature could be inserted).
The generated pdf-file "result.pdf" cannot be opened in Acrobat Reader. Acrobat Reader shows only the original pdf "original.pdf", but does not display the signature-image. It says "error in page. please contact the creator of the pdf".
However, most images can be inserted, so it is likely that the problem depends on the very image used.
The images are all ok, they are png's and where checked and verified with various imaging programs, e.g. gimp or irfanview.
Furthermore, the code above has always worked fine with PdfBox 2.08. After an update of PdfBox to version 2.12, the problem showed up and also the newest version 2.16 still produces the error. Still on the same image files, and still not on all.
NB: When I put the following line into comment, then no error shows up in Acrobat Reader, so the problem must be somewhere within drawImage.
// content.drawImage (pdImage, 50.0f, 350.0f, 100.0f, 25.0f);
and the rest of the code seems to be fine.
Also, I've just tried starting with an empty PDF and not loading an already generated one.
PDDocument document = new PDDocument ();
PDPage page = new PDPage ();
document.addPage (page);
[...]
The problem here is still the same, so the issue does not depend on the underlying PDF.
It is a bug since 2.0.12 (wrong alternate colorspace for gray images created with the LosslessFactory) that has been fixed in PDFBOX-4607 and will be in release 2.0.17. Display works for all viewers I have tested except Adobe Reader, despite that the alternate colorspace shouldn't be used when an ICC colorspace is available. Here's some code to fix PDFs (this assumes that images are only on top level of a page, i.e. images in other structures are not considered)
for (PDPage page : doc.getPages())
{
PDResources resources = page.getResources();
if (resources == null)
{
continue;
}
for (COSName name : resources.getXObjectNames())
{
PDXObject xObject = resources.getXObject(name);
if (xObject instanceof PDImageXObject)
{
PDImageXObject img = (PDImageXObject) xObject;
if (img.getColorSpace() instanceof PDICCBased)
{
PDICCBased icc = (PDICCBased) img.getColorSpace();
if (icc.getNumberOfComponents() == 1 && PDDeviceRGB.INSTANCE.equals(icc.getAlternateColorSpace()))
{
List<PDColorSpace> list = new ArrayList<>();
list.add(PDDeviceGray.INSTANCE);
icc.setAlternateColorSpaces(list);
}
}
}
}
}

Insert Image to existing non-empty pdf [duplicate]

This question already has answers here:
Table disappears when drawn before contentStream - PDFBox with Boxable
(1 answer)
PDFBox : PDPageContentStream's append mode misbehaving
(1 answer)
Cannot figure out how to use PDFBox
(2 answers)
Closed 3 years ago.
I'm trying to save an image into an existing pdf using apache PDFBOX,but my contents are getting deleted and i get blank document when I place the image on top of the pdf,Is there a solution to the problem?
My Code Looks like this.
public class TestPdfImage {
public static void main(String args[]) throws Exception {
//Loading an existing document
File file = new File("...../mydoc.pdf");
PDDocument doc = PDDocument.load(file);
//Retrieving the page
PDPage page = doc.getPage(0);
//Creating PDImageXObject object
PDImageXObject pdImage = PDImageXObject.createFromFile("...../sample.png",doc);
//creating the PDPageContentStream object
PDPageContentStream contents = new PDPageContentStream(doc, page);
//Drawing the image in the PDF document
contents.drawImage(pdImage, 70, 250);
System.out.println("Image inserted");
//Closing the PDPageContentStream object
contents.close();
//Saving the document
doc.save(".../sample.pdf");
//Closing the document
doc.close();
}
}
Try to use the append-mode
//creating the PDPageContentStream object
PDPageContentStream contents = new PDPageContentStream(doc, page, AppendMode.APPEND, true);
Edit
TilmanHausherr mentioned
new PDPageContentStream(doc, page, AppendMode.APPEND, true, true);
Thats why

How to add text watermark to pdf in Java using Apache PDFBox?

I am not getting any tutorial for adding a text watermark in a PDF file? Can you all please guide me, I am very new to PDFBOX.
Its not duplicate, the link in the comment didn't help me. I want to add text, not an image to the pdf.
Here is an example using PDFBox 2.0.2. This will load a PDF and write some text in the bottom right corner in a red transparent font. If it is a multiple page PDF the watermark will appear on every page. It might not be production ready, as I am not sure if there are some additional null conditions that need to be checked, but it should get you running in the right direction.
Keep in mind that this particular block of code will not modify the original PDF, but will create a new PDF using the Tmp_(filename) as the output.
private static void watermarkPDF (File fileStored) {
File tmpPDF;
PDDocument doc;
tmpPDF = new File(fileStored.getParent() + System.getProperty("file.separator") +"Tmp_"+fileStored.getName());
doc = PDDocument.load(fileStored);
for(PDPage page:doc.getPages()){
PDPageContentStream cs = new PDPageContentStream(doc, page, AppendMode.APPEND, true, true);
String ts = "Some sample text";
PDFont font = PDType1Font.HELVETICA_BOLD;
float fontSize = 14.0f;
PDResources resources = page.getResources();
PDExtendedGraphicsState r0 = new PDExtendedGraphicsState();
r0.setNonStrokingAlphaConstant(0.5f);
cs.setGraphicsStateParameters(r0);
cs.setNonStrokingColor(255,0,0);//Red
cs.beginText();
cs.setFont(font, fontSize);
cs.setTextMatrix(Matrix.getTranslateInstance(0f,0f));
cs.showText(ts);
cs.endText();
}
cs.close();
}
doc.save(tmpPDF);
}

Categories

Resources