MiSt
MiSt

Reputation: 43

iTextPdf not loading Images correctly

Heyo, i have a problem with this piece of code:

  private void createPDF(String[] url, String name) throws FileNotFoundException, DocumentException, IOException{
    com.itextpdf.text.Document document = new com.itextpdf.text.Document();
    FileOutputStream fos = new FileOutputStream(name);
    PdfWriter writer = PdfWriter.getInstance(document, fos);
    writer.open();
    document.open();
    document.setMargins(1, 0, 0, 0);
    document.addTitle(name);
    document.addSubject(name);
    for (String url1 : url) {
      Image i = Image.getInstance(new java.net.URL(url1));
      i.scaleToFit(document.getPageSize());
      document.add(i);
      document.newPage();
      writer.flush();
    }
    document.close();
    writer.close();
  }

The Images are jpeg formatted and on a server an I am using iText-pdfa-5.5.5 with iText-xtra-5.5.5 via Maven.

The Problem is, that some pictures are not displayed correctly but like cut in halve. How can I prevent this to happen?

What I tried until now:

both with the same result.

Please help me.


okay i just inserted (with getImage beeing from Bruno Lowagies code below)

  BufferedImage read = ImageIO.read(new ByteArrayInputStream(getImage(new java.net.URL(url1))));
  ImageIO.write(read, "jpeg", new File(url1.substring(url1.length()-8, url1.length())));
  Image i = Image.getInstance(read, null);

and the Files I get arent fully downloaded and the bottom part of the picture seems to be filled with #808080

Upvotes: 0

Views: 4047

Answers (1)

Bruno Lowagie
Bruno Lowagie

Reputation: 77528

iText doesn't change a singe byte of a JPG image. It just takes the bytes it receives and puts them inside the PDF in a stream defining the /Filter as /DCTDecode, so there should be no problem importing JPG images.

However, looking at your code, I see that you expect the Image object to load the file from an URL: new java.net.URL(url1) and I remember people having problems similar to yours because the InputStream obtained from the URL object wasn't always fully read when url1 wasn't a file URL, but an URL to some image on the web.

This problem was inherent to reading InputStreams: the Image needs to read the first bytes of the InputStream first to determine the image type, and then go back to the start of the InputStream to read the full image.

To work around this problem, it is better to read the image into a byte[] first and to use this byte[] as a parameter for the Image constructor.

Something like this:

public byte[] getImage(URL url) throws IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    InputStream is = url.openStream ();
    byte[] b = new byte[4096];
    int n;
    while ( (n = is.read(b)) > -1 ) {
        baos.write(b, 0, n);
    }
    return baos.toByteArray();
}

And then:

Image i = Image.getInstance(getImage(new java.net.URL(url1)));

I wrote these code snippets without testing. Please let me know if they work (or update my answer if I made some typos).

Upvotes: 2

Related Questions