8

In my current project, I try to add a BufferedImage to a PDFBox document. More specificly, I use an image from a JFreeChart. My code looks like this:

public void exportToPDF(JFreeChart chart, String filePath){
    PDDocument doc = null;
    PDPage page = null;
    PDXObjectImage ximage = null;

    try {
        doc = new PDDocument();
        page = new PDPage();
        doc.addPage(page);
        PDPageContentStream content = new PDPageContentStream(doc, page);
        BufferedImage image = chart.createBufferedImage(300, 300);
        ximage = new PDJpeg(doc, image);
        content.drawImage(ximage, 20, 20);
        content.close();
    } catch(IOException ie) {
    }
    doc.save(filePath);
    doc.close();
}

The document gets created; I can add text, but I get an error stating the the image does not have enough information to be shown.

Any clue to what I am doing wrong?

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
Oglop
  • 260
  • 1
  • 3
  • 11
  • The error message is displayed in the generated pdf file, I should have been clear on that. When i open the file it dislays all text as it should but instead of an image i get a message "Unsufficient data to display image". Im more or less green when it comes to siplaying images so any ideas are welcomed – Oglop Aug 14 '11 at 12:16
  • This might be this bug: https://issues.apache.org/jira/browse/PDFBOX-2026 It will be fixed in 1.8.5. Or download a snapshot. – Tilman Hausherr Apr 16 '14 at 10:02

3 Answers3

7

Thanks for helping me out trashgod. Spent last night and a few hours today beeing confused about PipedIn/OutStreams. Can´t figure it out. However, i got it to work. Turns out it wasn´t very difficult at all.

public void exportToPDF(JFreeChart chart, String filePath){
    PDDocument doc = null;
    PDPage page = null;
    PDXObjectImage ximage = null;
    try {
        doc = new PDDocument();
        page = new PDPage();
        doc.addPage(page);
        PDPageContentStream content = new PDPageContentStream(doc, page);

        //create a new outStream
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ChartUtilities.writeChartAsJPEG(out, chart, 300, 300);//write to outstream
        //create a new inputstream
        InputStream in = new ByteArrayInputStream(out.toByteArray());
        ximage = new PDJpeg(doc, in);
        content.drawImage(ximage, 5, 300);
        content.close();
    }
    catch (IOException ie){
        //handle exception
    }
    //save and close
    doc.save(filePath);
    doc.close();
}

I´m sure this can be done better but it works.

Oglop
  • 260
  • 1
  • 3
  • 11
5

There is an easy way to insert a JFreeChart into a pdf with pdfbox:

BufferedImage bufferedImage = source.getChart().createBufferedImage(source.getWidth(),
        source.getHeight(), BufferedImage.TYPE_INT_RGB, null);
PDXObjectImage ximage = new PDJpeg(doc, bufferedImage);

Without any stream ;)

Kasas
  • 1,216
  • 2
  • 18
  • 28
3

Two things stand out:

  • Do not swallow exceptions.

  • Do use ChartUtilities to render the image in a suitable format, as suggested here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • So i looked at what you said, i can get an outputStream by using: OutputStream out = new ByteArrayOutputStream(); and then: ChartUtilities.writeChartAsJPEG(out, chart, 300, 300); however, i can´t figure out how to turn this into an inputstream. – Oglop Aug 14 '11 at 20:44
  • To move data from an `OutputStream` to an `InputStream` use piped streams, shown [here](http://stackoverflow.com/questions/4443878/redirecting-system-out-to-jtextpane/4444677#4444677) and [here](http://stackoverflow.com/questions/484119/why-doesnt-more-java-code-use-pipedinputstream-pipedoutputstream). – trashgod Aug 14 '11 at 22:15
  • Also, you can just save the image as a file or cache its byte array. Also consider the `PNG` v `JPG` [tradeoff](http://www.turnkeylinux.org/blog/png-vs-jpg). – trashgod Aug 15 '11 at 01:27