8

In my application i want to convert the images selected by the user into one single PDF file. I am using iText library as suggested by many people. The user selects multiple images and one pdf is created with it where each image is 1 pdf page.

The Code i am using is give as below

    Document document = new Document(PageSize.A4);
            try {

                String path = Environment.getExternalStorageDirectory()+"/PDFile.pdf";

                File file= new File(path);

                if(file.exists())
                {

                }
                else
                {
                    file.createNewFile();
                }


                PdfWriter.getInstance(document,new FileOutputStream(path));

                document.open();

                for(int i =0; i<pdfImage.size();i++)
                {
                    Image image = Image.getInstance(pdfImage.get(i));
                    image.scaleAbsolute(PageSize.A4);
                    image.setAbsolutePosition(0, 0);
                    document.add(image);

                }

                document.close();



            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

The pdf is getting generated but the image is cropped. Only half of the image is visible rest of it is cropped.

Do i have to set anything for the pdf to adopt to the image size ??

Or do i have to change or resize the image to adopt to pdf page size??

Please help!! I have no idea how to resolve this???

shivani
  • 746
  • 3
  • 22
  • 40

2 Answers2

14

When you do this:

Document document = new Document();

Then you implicitly create a document of which the pages have a page size known as A4. That is: a width of 595 and a height 842 user units.

If you add images that are smaller, they won't be cropped. If you add images that are bigger. The images will be cropped...

If you want an image to fit a page exactly, you have two options:

  1. Adapt the size of the pages, or
  2. Adapt the size of the image.

Both options are equivalent, as iText will not change the resolution of the images: every pixel will be preserved.

Option 1:

See my answer to the question: Adding maps at iText Java

In this question, I do this:

Image img = Image.getInstance(IMG);
Document document = new Document(img);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
img.setAbsolutePosition(0, 0);
document.add(img);
document.close();

The Document object accepts a Rectangle as parameter. This Rectangle defines the page size in user units. As the Image class is a subclass of the Rectangle class, I can use the Image instance as a parameter to create the Document instance.

Another option would be to do this:

Rectangle pagesize = new Rectangle(img.getScaledWidth(), img.getScaledHeight());
Document document = new Document(pagesize);

If your document has different pages, you must use the setPageSize() method before triggering a new page.

Option 2:

See my answer to the question: Backgroundimage in landscape and cover whole pdf with iTextSharp

The code looks like this (well, the actual code is a tad different, but this will work too):

Document document = new Document(PageSize.A4.rotate());
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
Image image = Image.getInstance(IMAGE);
image.scaleAbsolute(PageSize.A4.rotate());
image.setAbsolutePosition(0, 0);
document.add(image);
document.close();

Here I have pages with size A4 in landscape, and I scale the image so that it fits the page completely. That is dangerous because this changes the aspect-ratio of the image. This can result in distorted images. Replacing scaleAbsolute() by scaleToFit() will avoid that problem, but you'll have some white margins if the aspect-ratio of the image is different from the aspect-ratio of the page.

Important: Note that I used setAbsolutePosition(0, 0); in both cases. I am introducing this line so that the lower-left corner of the image coincides with the lower-left corner of the page. If you don't do this, you will see a margin to the bottom and to the left, and your image will be clipped to the top and the right.

Community
  • 1
  • 1
Bruno Lowagie
  • 75,994
  • 9
  • 109
  • 165
  • how can i use this for putting multiple images as pages in a pdf??? i tried your code as in my edited question where i am getting a single pdf with one page only with the last image..Please check and let me know where i went wrong with your code... – shivani Nov 24 '14 at 12:26
  • Isn't it obvious that you should add `document.newPage()` each time you've added an image at an absolute position on the current page? ;-) – Bruno Lowagie Nov 24 '14 at 12:27
  • Sorry, my bad! It worked! I am not quite familiar with playing around with pdfs in android..so i didn't know exactly what else to write..Using this for the first time.. Anyways,Thanks a lot! – shivani Nov 24 '14 at 12:37
  • I have tried all these methods. But all these are working extremely slow. I am using this on android. – Aditya Chaudhary Sep 12 '16 at 08:30
  • @AdityaChaudhary The iText execution of these methods are extremely fast because they don't require any image manipulation. However, in case of really large images, there could be issues with disk access and allocating memory for the images. Maybe you have a poor Android device. You shouldn't blame iText for the slow disk access, poor CPU and possibly low memory of the device. – Bruno Lowagie Sep 12 '16 at 08:52
  • I was testing on LG Nexus 5, which is a pretty decent device. – Aditya Chaudhary Nov 28 '16 at 10:06
0

This is an old post and you may have already sorted this out, but another alternative would be using a table in iText.

Set the margins of your document, then create a table that has a single cell that spans the full width of the allowable page. When you add an image to that cell, it will use the cell dimensions as the limiting factors for the picture size and should re-scale the image to fit in the cell automatically.

If you don't like the looks of a table with borders, you can always turn those off, but the cells may also give you some other formatting options like being able to center the image in the cell (on the page).

Good luck.

Matthew
  • 139
  • 1
  • 10
  • Hi Matthew, thanks for your answer about scaling images to page size via iText. Could you add some sample code to your text, please, in order to make your answer clearer? Thanks. – CKE Oct 04 '19 at 04:50