How do I add an image to a new A4 PDF document in Java

I want to convert images (lets limit to jpg here) to a PDF.

I have tried this snippet, gleaned from here:

com.aspose.pdf.Document pdfDoc = new com.aspose.pdf.Document();
Page page = pdfDoc.getPages().add();
page.getResources().getImages().add(conversionDto.getInputStream());
page.getContents().add(new GSave());

com.aspose.pdf.Rectangle rect = page.getRect();
Matrix matrix = new Matrix(new double[] {rect.getURX() - rect.getLLX(), 0, 0, rect.getURY()-rect.getLLY(), rect.getLLX(), rect.getLLY() });
page.getContents().add(new ConcatenateMatrix(matrix));
XImage ximage = page.getResources().getImages().get_Item(page.getResources().getImages().size());
page.getContents().add(new Do(ximage.getName()));
page.getContents().add(new GRestore());
pdfDoc.save(conversionDto.getOutputStream());

conversionDto contains the source file inputStream. We successfully use this technique to convert Word docs and Excel spreadsheets to PDF files using the wWords etc packages

When I run this I get what seems like an empty PDF.

What I’m after is a way to convert a jpeg, often of large size, to an A4 PDF with the image appropriately resized to about 300 dpi. Either the PDF page has to match the image orientation, or I need to rotate the image to match a standard portrait PDF page.

What am I doing wrong…?

@rouppe

Is it possible if you can please share the sample source and output files for our reference? We will test the scenario in our environment and address it accordingly.

Please find attached…

My goal is to be able to turn an image into a single page pdf, A4 size, properly oriented depending on the source image orientation, scaled appropriately if necessary to save space. My source jpg is actually 3.1Mb but uploading it here seems to cut it to 321KB

FerryQueue.jpg (321.0 KB)
rouppe.pdf (2.2 KB)

In addition I have tried this method:

        com.aspose.pdf.Document pdfDoc = new com.aspose.pdf.Document();
        Page page = pdfDoc.getPages().add();
        page.getPageInfo().setMargin(new MarginInfo(20, 20, 20, 20));

        Image image = new Image();
        image.setImageStream(conversionDto.getInputStream());
        if ( image.getFixWidth() > image.getFixHeight() ) {
            page.getPageInfo().setLandscape(true);
        }
        page.getParagraphs().add(image);
        pdfDoc.save(conversionDto.getOutputStream());

I get a pdf with the image in it but the image doesn’t give me any information to determine if its landscape or not (getFixedWidth() and getFixedHeight() return 0) so the image is squashed in portrait orientation - that is it has been resized horizontally only (not proportionally)

@rouppe

Is it possible if you could please share an expected output PDF as well where the size is A4 and image is properly oriented and scaled? It would help us in investigating the case accordingly.

This is the output we currently get with iText. We are trying to wean ourselves off two products that do similar things.

Note that it is not oriented as landscape (source image orientation), which is something I’d want to do with an Aspose solution. But as far as everything else goes, my understanding is it is A4

rouppe.pdf (3.0 MB)

And just for clarity, the source image is just an example from my phone. We could be provided with photo’s, in any of the aspect ratios (16:9, 3:2, square) or a screensot taken at completely random dimensions (tall and skinny, short and wide…).

I want to plonk it into an A4 page, have it maintain aspect ratio and save it.

Kind regards, Andrew

@rouppe

Just to clarify - as per our understandings, you want to add an image to PDF file while retaining the scaling of the image and fit it into A4 dimensions. It does not matter which size the image has, you need to have PDF output in A4 size with portrait orientation? Right?

Thanks for your attention to this.

Basically.

I’d prefer that an image that was wider than it was higher be put into an A4 page set to landscape, but essentially we want an A4 page output, with the image placed in it in a way that reflects its original aspect ratio.

@rouppe

Thanks for explanations. We are trying to create a sample code snippet that could achieve what you desire. We will be sharing it with you shortly.

We have ended up doing this, which seems to work

            final BufferedImage read = ImageIO.read(conversionDto.getInputStream());

            Page page = pdfDoc.getPages().add();
            PageInfo pageInfo = page.getPageInfo();

            // Load image to determine whether it is wider than higher, in which case set the page to landscape
            final Image image = new Image();
            image.setBufferedImage(read);
            final BufferedImage bufferedImage = image.getBufferedImage();
            if (bufferedImage.getWidth() > bufferedImage.getHeight()) {
                pageInfo.setLandscape(true);
            }

            pageInfo.setMargin(new MarginInfo(PAGE_MARGIN_SIZE, PAGE_MARGIN_SIZE, PAGE_MARGIN_SIZE, PAGE_MARGIN_SIZE));
            page.getParagraphs().add(image);
            pdfDoc.save(conversionDto.getOutputStream());

@rouppe

It is nice to know that you were able to make it work. Please keep using the API and feel free to let us know in case you need some more information.