使用Itext从pdf检索图像时出错

时间:2015-08-12 10:22:52

标签: java pdf itext pdf-parsing

我有一个现有的PDF,我想从中检索图像

注意:

在文档中,这是 RESULT 变量

public static final String RESULT = "results/part4/chapter15/Img%s.%s";

我不明白为什么需要这张图片?我只想从PDF文件中提取图片

所以现在我使用MyImageRenderListener listener = new MyImageRenderListener(RESULT);

我收到错误:

  

results \ part4 \ chapter15 \ Img16.jpg(系统   找不到指定的路径)

这是我的代码。

    package part4.chapter15;

    import java.io.IOException;


    import com.itextpdf.text.DocumentException;
    import com.itextpdf.text.pdf.PdfReader;
    import com.itextpdf.text.pdf.parser.PdfReaderContentParser;

    /**
     * Extracts images from a PDF file.
     */
    public class ExtractImages {

    /** The new document to which we've added a border rectangle. */
    public static final String RESOURCE = "resources/pdfs/samplefile.pdf";
    public static final String RESULT = "results/part4/chapter15/Img%s.%s";
    /**
     * Parses a PDF and extracts all the images.
     * @param src the source PDF
     * @param dest the resulting PDF
     */
    public void extractImages(String filename)
        throws IOException, DocumentException {
        PdfReader reader = new PdfReader(filename);
        PdfReaderContentParser parser = new PdfReaderContentParser(reader);
        MyImageRenderListener listener = new MyImageRenderListener(RESULT);
        for (int i = 1; i <= reader.getNumberOfPages(); i++) {
            parser.processContent(i, listener);
        }
        reader.close();
    }

    /**
     * Main method.
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        new ExtractImages().extractImages(RESOURCE);
    }
}

1 个答案:

答案 0 :(得分:2)

你有两个问题,第一个问题的答案是第二个答案的关键。

问题1:

您可以参考:

public static final String RESULT = "results/part4/chapter15/Img%s.%s";

你问:为什么需要这张图片?

这个问题是错误的,因为Img%s.%s不是图像的文件名,它是图像文件名的模式。在解析时,iText将检测PDF中的图像。这些图像存储在编号对象(例如对象16)中,这些图像可以以不同的格式导出(例如jpg,png,...)。

假设图像存储在对象16中并且该图像是jpg,则该图案将解析为Img16.jpg

问题2:

为什么我会收到错误:

  

结果\ part4 \ chapter15 \ Img16.jpg(系统找不到指定的路径)

在您的PDF中,存储在对象16中的jpg。您要求iText使用此路径存储该图像:results\part4\chapter15\Img16.jpg(如我对问题1的回答中所述)。但是:您的工作目录没有子目录results\part4\chapter15\,因此会抛出IOException(或FileNotFoundException?)。

一般问题是什么?

您已复制/粘贴了我为我的书写的ExtractImages示例&#34; iText in Action - Second Edition&#34;,但是:

  1. 你没看过那本书,所以你不知道该代码应该做什么。
  2. 你并没有在StackOverflow上告诉读者这个例子取决于MyImageRenderer类,这就是所有魔法发生的地方。
  3. 您如何解决问题?

    选项1:

    像这样更改RESULT

    public static final String RESULT = "Img%s.%s";
    

    现在图像将存储在您的工作目录中。

    选项2:

    调整MyImageRenderer类,更具体地说是这个方法:

    public void renderImage(ImageRenderInfo renderInfo) {
        try {
            String filename;
            FileOutputStream os;
            PdfImageObject image = renderInfo.getImage();
            if (image == null) return;
            filename = String.format(path,
                renderInfo.getRef().getNumber(), image.getFileType());
            os = new FileOutputStream(filename);
            os.write(image.getImageAsBytes());
            os.flush();
            os.close();
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }
    

    只要遇到图像,iText就会调用此类。它将ImageRenderInfo传递给此方法,该方法包含有关该图像的大量信息。

    在此实现中,我们将图像字节存储为文件。这就是我们创建该文件路径的方式:

    String.format(path,
         renderInfo.getRef().getNumber(), image.getFileType())
    

    正如您所看到的,RESULT中存储的模式的使用方式是%s的第一次出现被一个数字替换,第二次出现的是文件扩展名。

    您可以轻松调整此方法,以便将图像byte[]存储在List中,如果这是您想要的。