3

I am using PDFBox v2 to convert jpg images to PDF. JPG image is already on the filesystem, so I just pick it up and convert it to PDF. Below is my code

public void convertImgToPDF(String imagePath, String fileName, String destDir) throws IOException {
        PDDocument document = new PDDocument();
        InputStream in = new FileInputStream(imagePath);
        BufferedImage bimg = ImageIO.read(in);
        float width = bimg.getWidth();
        float height = bimg.getHeight();
        PDPage page = new PDPage(new PDRectangle(width, height));
        document.addPage(page);
        PDImageXObject img = PDImageXObject.createFromFile(imagePath, document);
        PDPageContentStream contentStream = new PDPageContentStream(document, page);
        contentStream.drawImage(img, 0, 0);
        contentStream.close();
        in.close();
        document.save(destDir + "/" + fileName + ".pdf");
        document.close();
    }

This code does the conversion just fine. However, I have observed the following in converted PDFs

  1. When I open a converted PDF, it opens very slowly (in Acrobat reader). It seems as it PDF is opening pixel by pixel. If I open any other PDF, it opens just fine.
  2. The default size in acrobat reader is shown to a smaller value (like 15% or 24%, screenshot attached) for converted PDFs. Even though it covers 100% of the screen (15% sould have implied that I see a much smaller image, but that is not the case). When I change the size to 100%, I see a highly blurred image which is much larger than the actual image and I have to scroll left/right and top/down to see the complete image.

Both these observations make me feel that for some reason the PDF that is getting generated is a much higher resolution than it should have been. Would that be a fair statement? If so, how can I correct this?

PDF size

EDIT Attached the JPG image which is being converted to PDF. When I open the PDF, it shows a size of 25.9%. This image was clicked on iPad.

Image to be converted to PDF

kayasa
  • 2,055
  • 8
  • 37
  • 63
  • 1
    Please share the image in question to reproduce the issue. – mkl Oct 10 '16 at 05:14
  • `new PDPage(new PDRectangle(width, height))` is not a good idea, the sizes are in page units, 1 unit = 1/72 inch. – Tilman Hausherr Oct 10 '16 at 06:29
  • Thanks @TilmanHausherr, so what should I be using instead? – kayasa Oct 10 '16 at 06:54
  • I have attached a sample JPG image – kayasa Oct 10 '16 at 07:54
  • @kayasa I've deleted my earlier comment, it is more complex and I'm confused myself now. I can't really answer, but now I think, page size and image scale should be seen separately. I.e. 1) decide on a page size, 2) decide on a scale for image display so that it fits. For your example, dividing by 3 and scaling the image by 3 worked nicely for some reason. With an A4 paper size by using `new PDPage()`, `contentStream.drawImage(img, 0, 0, width / 6, height / 6);` leaves some blank area. – Tilman Hausherr Oct 10 '16 at 09:04

1 Answers1

0

There is an overloaded drawImage() method to do that

contentStream.drawImage(PDImageXObject, float x, float y)
contentStream.drawImage(PDImageXObject, float x, float y, float height, float width)

By specifying explicit width and height on contentStream.drawImage(), this can be achieved. For instance if you want to show the image 4 times smaller but still retain the same resolution, it can done using

scaleDownRatio = 0.25;
pageSize = PDRectangle.A4;

# this will draw image at bottom left corner
PDImageXObject pageImageXObject = LosslessFactory.createFromImage(document, bitmap);
contentStream.drawImage(pageImageXObject, 0, 0, bitmap.getWidth() * ratio, bitmap.getHeight() * ratio)

# to center it you can use something like
contentStream.drawImage(pageImageXObject, (pageSize.getWidth() - bitmap.getWidth() * ratio) / 2, (pageSize.getHeight() - bitmap.getHeight() * ratio) / 2, bitmap.getWidth() * ratio, bitmap.getHeight() * ratio)

Note: in your case, the image wouldn't still fit in even after scaling it to one-fourth the size; You can get the scale factor by

float widthRatio = bitmap.getWidth() / pageSize.getWidth();
float heightRatio = bitmap.getHeight() / pageSize.getHeight();
scaleDownRatio = (widthRatio<heightRatio)? widthratio:heightRatio;
Saravanabalagi Ramachandran
  • 8,551
  • 11
  • 53
  • 102