【问题标题】:Creating PDF from TIFF image using iText使用 iText 从 TIFF 图像创建 PDF
【发布时间】:2011-12-05 00:09:48
【问题描述】:

我目前正在使用 iText 从 TIFF 图像生成 PDF 文件。

基本上流程如下: 1. 阅读 TIFF 文件。 2. 对于 TIFF 的每个“页面”,实例化一个 Image 对象并将其写入 Document 实例,即PDF文件。

我很难理解如何将这些图像添加到 PDF 中以保持原始分辨率。

我尝试将 Image 缩放到 TIFF 原始图像的像素尺寸,例如:

// 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);

如果有人能对此有所了解,我将不胜感激。也许我缺少 Image 类方法的功能...

提前致谢!

【问题讨论】:

    标签: java itext


    【解决方案1】:

    我认为如果您缩放图像,则无法保留原始分辨率(如果我错了,请纠正我:))。 您可以尝试做的是创建具有不同大小页面的 PDF 文档(如果图像在 tif 图像中具有不同的分辨率)。

    试试下面的代码。它将 PDF 页面的大小设置为等于图像文件的大小,然后创建该 PDF 页面。 PDF 页面大小因图像大小而异,因此分辨率保持不变:)

    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();
    
        }
    
    }
    

    【讨论】:

    • 谢谢秋刀鱼!您是否在不丢失分辨率的情况下测试了此代码?我试了一下,我得到的是一个 PDF 页面,其中包含一个比它可以容纳的更大的图像......
    • 见代码“Rectangle pageSize = new Rectangle(image.getWidth(), image.getHeight());”。我要做的基本上是获取图像的实际大小,然后创建一个相同大小的空白 PDF 页面,这样当 PDF 嵌入 PDF 页面时,图像不会失去其质量。这就是为什么根据我的代码你会得到不同大小的页面 PDF。如果您不这样做,那么您最终将在图像上执行 scaleToFit,这将导致图像数据丢失(在放大 PDF 页面时可识别)。最终我试图避免 scaleToFit 调用。
    【解决方案2】:

    我发现这条线不好用:

    document.setPageSize(pageSize);
    

    如果您的 TIFF 文件只包含一张图片,那么您最好使用它:

    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();
    

    这将产生与图像大小完全匹配的页面大小,因此不需要缩放。

    【讨论】:

      【解决方案3】:

      另一个示例不推荐使用,直到 iText 5.5,第一页问题已修复。我正在使用 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();            
          }
      }
      

      【讨论】:

      • 我确认这是用于使图像正确适合每个页面的解决方案。谢谢!
      • 我知道有点晚了,但是你能不能也写下你使用的导入?因为对于原始和最新的 iText 库(不是 lowagie 的),此代码不起作用。 TiffImage.getNumberOfPages(rafa) 必须替换为 TiffImageData.getNumberOfPages(rafa)TiffImage.getTiffImage(rafa, i) 根本不起作用,因为该方法需要 com.itextpdf.text.pdf.RandomAccessFileOrArray 但我们有 com.itextpdf.io.source.RandomAccessFileOrArray
      • 这不是相同的代码,它甚至不使用 iText,而是使用 ICEPdf。
      • 我的错误。 jcgonzalez.com/java-tiff-pdf-example第4点。这里也加了。
      • 谢谢。在这一点上,我不能再告诉我做错了什么,因为我更改了很多代码(我现在正在使用 iText 7),但我尝试使用 iText 5.5.11 进行这些导入并且没有错误。再次感谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-28
      • 2016-04-04
      相关资源
      最近更新 更多