Writing image into pdf file in java

2019-03-29 01:53发布

问题:

I'm writing a code to convert Microsoft power-point(ppt) slides into images and to write the generated images into pdf file. Following code generates and writes the images into pdf file but the problem i'm facing is, when i write image into pdf file it's size is exceeding the pdf page size and i can view only 75% of the image rest is invisible. One more thing to notice here is, written images in pdf file look like zoomed or expanded. Take a look at the following snippet of code:

for (int i = 0; i < slide.length; i++) {
    BufferedImage img = new BufferedImage(pgsize.width, pgsize.height,   BufferedImage.TYPE_INT_RGB);
    Graphics2D graphics = img.createGraphics();
    graphics.setPaint(Color.white);
    graphics.fill(new Rectangle(0, 0, pgsize.width, pgsize.height));
    slide[i].draw(graphics);
    fileName="C:/DATASTORE/slide-"+(i+1)+".png";
    FileOutputStream out = new FileOutputStream(fileName);
    javax.imageio.ImageIO.write(img, "png", out);
out.flush();
out.close();
com.lowagie.text.Image image =com.lowagie.text.Image.getInstance(fileName);
            image.setWidthPercentage(40.0f);
    doc.add((image));
    }

doc.close();
} catch(DocumentException de) {
          System.err.println(de.getMessage());
    }

If anybody knows the solution please help me to rectify. Thank you.

Here is the code it accomplishes the task i wished. Now i'm getting the desired results after following Bruno Lowagie recommendations.

But, as Bruno Lowagie pointed out earlier, their is a problem in generated png image. The generated png image is not correct because shape or image in the slide overlaps with the texts of the slide. Can you help me to identify and rectify the error?

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import com.itextpdf.text.Image;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.hslf.model.Slide;
import org.apache.poi.hslf.usermodel.SlideShow;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
public class ConvertSlidesIntoImages {
    public static void main(String[] args){
    try {
        FileInputStream is = new FileInputStream("C:/DATASTORE/testPPT.ppt");
        SlideShow ppt = new SlideShow(is);
        is.close();
        String fileName;
        Dimension pgsize = ppt.getPageSize();
        Slide[] slide = ppt.getSlides();
        Document doc=new Document();
        PdfWriter.getInstance(doc, new  FileOutputStream("c:/DATASTORE/convertPPTSlidesIntoPDFImages.pdf"));
        doc.open();

        for (int i = 0; i < slide.length; i++) {
            BufferedImage img = new BufferedImage(pgsize.width, pgsize.height, BufferedImage.TYPE_INT_RGB);
            Graphics2D graphics = img.createGraphics();
            graphics.setPaint(Color.white);
            graphics.fill(new Rectangle(0, 0, pgsize.width, pgsize.height));
            slide[i].draw(graphics);
            fileName="C:/DATASTORE/slide-"+(i+1)+".png";
            FileOutputStream out = new FileOutputStream(fileName);
            javax.imageio.ImageIO.write(img, "png", out);
            out.flush();
            out.close();
            com.itextpdf.text.Image image =com.itextpdf.text.Image.getInstance(fileName);
            doc.setPageSize(new com.itextpdf.text.Rectangle(image.getScaledWidth(), image.getScaledHeight()));
            doc.newPage();
            image.setAbsolutePosition(0, 0);
            doc.add(image);
            }
    doc.close();
}catch(DocumentException de) {
    System.err.println(de.getMessage());
    }
    catch(Exception ex) {
    ex.printStackTrace();
    }
}

Thank you

回答1:

First this: If the png stored as "C:/DATASTORE/slide-"+(i+1)+".png" isn't correct, the slide in the PDF won't be correct either.

And this: Your code snippet doesn't show us how you create the Document object. By default, the page size is A4 in portrait. It goes without saying that images that are bigger than 595 x 842 don't fit that page.

Now the answer: There are two ways to solve this.

Either you change the size of the image (not with setWidthPercentage() unless you've calculated the actual percentage) and you add it a the position (0, 0) so that it doesn't take into account the margins. For instance:

image.scaleToFit(595, 842);
image.setAbsolutePosition(0, 0);
doc.add(image);
doc.newPage();

A better solution would be to adapt the size of the page to the size of the image.

Document doc = new Document(new Rectangle(image.getScaledWidth(), image.getScaledHeight()));
// create a writer, open the document
image.setAbsolutePosition(0, 0);
doc.add(image);
doc.newPage();

If the size of the images varies, you can change the page size while adding images like this:

doc.setPageSize(new Rectangle(image.getScaledWidth(), image.getScaledHeight()));
doc.newPage();
image.setAbsolutePosition(0, 0);
doc.add(image);

It is important to understand that the new page size will only come into effect after doc.newPage();

CAVEAT 1: If your PDF only holds the last slide, you're probably putting all the slides on the same page, and the last slide covers them all. You need to invoke the newPage() method each time you add an image (as done in a code snippet in my answer).

CAVEAT 2: Your allegation is wrong. According to the API docs, there is a method setPageSize(Rectangle rect), maybe you're using the wrong Rectangle class. If you didn't follow my advice (which IMHO wouldn't be wise), you're probably looking for com.lowagie.text.Rectangle instead of java.awt.Rectangle.

CAVEAT 3: This is similar to CAVEAT 2, there are indeed no such methods in the class java.awt.Image, but as documented in the API docs, the class com.itextpdf.text.Image has a getScaleWidth() method and a getScaledHeight() method.