2

I'm currently generating PDF files from TIFF images using iText.

Basically the procedure is as follows: 1. Read the TIFF file. 2. For each "page" of the TIFF, instantiate an Image object and write that to a Document instance, which is the PDF file.

I'm having a hard time understanding how to add those images to the PDF keeping the original resolution.

I've tried to scale the Image to the dimensions in pixels of the original image of the TIFF, for instance:

// Pixel Dimensions 1728 × 2156 pixels
// Resolution 204 × 196 ppi
RandomAccessFileOrArray tiff = new RandomAccessFileOrArray("/path/to/tiff/file");
Document pdf = new Document(PageSize.LETTER);
Image temp = TiffImage.getTiffImage(tiff, page);
temp.scaleAbsolute(1728f, 2156f);
pdf.add(temp);

I would really appreciate if someone can shed some light on this. Perhaps I'm missing the functionality of the Image class methods...

Thanks in advance!

romeroqj
  • 829
  • 3
  • 10
  • 21

3 Answers3

6

I've found that this line doesn't work well:

document.setPageSize(pageSize);

If your TIFF files only contain one image then you're better off using this instead:

RandomAccessFileOrArray ra = new RandomAccessFileOrArray(imageFilePath);
Image image = TiffImage.getTiffImage(ra, 1);
Rectangle pageSize = new Rectangle(image.getWidth(), image.getHeight());

Document document = new Document(pageSize);
PdfWriter writer = PdfWriter.getInstance(document,  new FileOutputStream(outputFileName));
writer.setStrictImageSequence(true);
document.open();
document.add(image);
document.newPage();

document.close();

This will result in a page size that fits the image size exactly, so no scaling is required.

try67
  • 61
  • 1
  • 2
6

I think if you scale the image then you can not retain the original resolution (please correct me if I am wrong :)). What you can try doing is to creat a PDF document with different sized pages (if images are of different resolution in the tif image).

Try the following code. It sets the size of PDF page equal to that of image file and then create that PDF page. the PDF page size varies according to the image size so the resolution is maintained :)

import java.io.FileOutputStream;
import java.io.IOException;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.RandomAccessFileOrArray;
import com.itextpdf.text.pdf.codec.TiffImage;

public class Tiff2Pdf {

    /**
     * @param args
     * @throws DocumentException
     * @throws IOException
     */
    public static void main(String[] args) throws DocumentException,
            IOException {

        String imgeFilename = "/home/saurabh/Downloads/image.tif";

        Document document = new Document();
        PdfWriter writer = PdfWriter.getInstance(
                document,
                new FileOutputStream("/home/saurabh/Desktop/out"
                        + Math.random() + ".pdf"));
        writer.setStrictImageSequence(true);
        document.open();

        document.add(new Paragraph("Multipages tiff file"));
        Image image;
        RandomAccessFileOrArray ra = new RandomAccessFileOrArray(imgeFilename);
        int pages = TiffImage.getNumberOfPages(ra);
        for (int i = 1; i <= pages; i++) {
            image = TiffImage.getTiffImage(ra, i);
            Rectangle pageSize = new Rectangle(image.getWidth(),
                    image.getHeight());
            document.setPageSize(pageSize);
            document.add(image);
            document.newPage();
        }

        document.close();

    }

}
Saurabh
  • 7,894
  • 2
  • 23
  • 31
  • 3
    thanks saury! have you tested this code without losing resolution? I gave it a shot and what I get is a PDF page containing an image bigger than what it can hold... – romeroqj Oct 12 '11 at 02:11
  • See the code " Rectangle pageSize = new Rectangle(image.getWidth(), image.getHeight());". What I am trying to do basically is to get the actual size of image and then create a blank PDF page of same size so that image does not lose its quality when PDF its embedded in PDF page. That is why as per my code you would get different sized page PDF. If you do not do this then you will end up doing scaleToFit on image which will introduce image data loss (identifiable when you zoom in the PDF page). Ultimately I was trying to avoid scaleToFit call. – Saurabh Oct 12 '11 at 02:47
1

Another example non-deprecated up to iText 5.5 with the first page issue fixed. I'm using 5.5.11 Itext.

import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import com.itextpdf.text.Document;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.io.FileChannelRandomAccessSource;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.RandomAccessFileOrArray;
import com.itextpdf.text.pdf.codec.TiffImage;
public class Test1 {
    public static void main(String[] args) throws Exception {
        RandomAccessFile aFile = new RandomAccessFile("/myfolder/origin.tif", "r");
        FileChannel inChannel = aFile.getChannel();
        FileChannelRandomAccessSource fcra =  new FileChannelRandomAccessSource(inChannel);
        Document document = new Document();
        PdfWriter.getInstance(document,  new FileOutputStream("/myfolder/destination.pdf"));
        document.open();              
        RandomAccessFileOrArray rafa = new RandomAccessFileOrArray(fcra);
        int pages = TiffImage.getNumberOfPages(rafa);
        Image image;
        for (int i = 1; i <= pages; i++) {            
            image = TiffImage.getTiffImage(rafa, i);
            Rectangle pageSize = new Rectangle(image.getWidth(), image.getHeight());
            document.setPageSize(pageSize);
            document.newPage();
            document.add(image);
        }
        document.close();
        aFile.close();            
    }
}
PbxMan
  • 7,525
  • 1
  • 36
  • 40
  • I confirm that this is the solution to use to get the image to fit correctly on every page. Thanks! – Paul Zepernick Apr 02 '15 at 12:33
  • I know it's a bit late but, can you please write the imports you used, too? Because with the original and latest iText libraries (not lowagie's) this code doesn't work. `TiffImage.getNumberOfPages(rafa)` has to be replaced with `TiffImageData.getNumberOfPages(rafa)` and `TiffImage.getTiffImage(rafa, i)` simply doesn't work because the method needs a `com.itextpdf.text.pdf.RandomAccessFileOrArray` but we have a `com.itextpdf.io.source.RandomAccessFileOrArray`. – nonzaprej Jun 27 '17 at 15:49
  • That's not the same code and it doesn't even use iText but ICEPdf. – nonzaprej Jun 27 '17 at 16:11
  • 1
    My mistake. http://www.jcgonzalez.com/java-tiff-pdf-example point number 4. It's added here too. – PbxMan Jun 28 '17 at 07:30
  • Thanks. At this point I can't tell anymore what I was doing wrong since I changed the code a lot (I'm using iText 7 now) but I tried those imports with iText 5.5.11 and there's no error. Thanks again. – nonzaprej Jun 28 '17 at 09:03