如何检查PDF页面是否为PDFBOX、XPDF扫描的图像?



PDFBox提取图像的问题。嗨,我如何检查pdf页面是否为图像并通过PDFBOX库提取图像,有一种方法可以获取图像,但如果pdf页面是图像,则无法获取。有人能帮我解决这个问题吗?

Xpdf问题提取图像。我尝试通过另一个库xpdf提取图像,如果它是图像,它会在页面上做奇怪的翻转。如果pdf包含一个小图像作为对象图像,它会给我好的,如果页面被扫描,我们在做翻转。

我想从PDF中提取所有图像,如果页面被扫描以获取它们作为图像,如果页面包含纯文本和图像也从该页获取图像。

我的观点是从PDF中提取所有图像。不仅形成一个页面,但即使页面是一个图像提取它们作为图像,但不要跳过它们是怎么做的,我认为PDFbox。

XPDF正在做一些事情,但有一个问题翻转(上,右)的页面当导出扫描页

我怎样才能解决这个问题呢?

下载测试文件示例

    `PDDocument document = PDDocument.load(new File("/home/dru/IdeaProjects2/PDFExtractor/test/t1.pdf"));
    PDPageTree list = document.getPages();
    for (PDPage page : list) {
        PDResources pdResources = page.getResources();
        System.out.println(pdResources.getResourceCache());
        for (COSName c : pdResources.getXObjectNames()) {
            PDXObject o = pdResources.getXObject(c);
            if (o instanceof org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject) {
                File file = new File("/home/dru/IdeaProjects2/PDFExtractor/test/out/" + System.nanoTime() + ".png");
                ImageIO.write(((org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject)o).getImage(), "png", file);
            }
        }
    }`

正确提取图像

作为更新的PDF明确的问题是,它没有任何图像立即在页面,但它有窗体xobjects绘制到它包含图像。因此,图像搜索必须递归为xobjects的形式。

这还不是全部:更新后的PDF中的所有页面共享相同的资源字典,它们只是选择一个不同的表单对象来显示。因此,必须解析相应的页面内容流,以确定给定页面上出现了哪个xobject(带有哪些图像)。

实际上这是PDFBox工具ExtractImages所做的事情。然而,不幸的是,它并没有显示它找到问题图像的页面,参见ExtractImages.java测试方法testExtractPageImagesTool10948New

但我们可以简单地借鉴该工具使用的技术:

PDDocument document = PDDocument.load(resource);
int page = 1;
for (final PDPage pdPage : document.getPages())
{
    final int currentPage = page;
    PDFGraphicsStreamEngine pdfGraphicsStreamEngine = new PDFGraphicsStreamEngine(pdPage)
    {
        int index = 0;
        
        @Override
        public void drawImage(PDImage pdImage) throws IOException
        {
            if (pdImage instanceof PDImageXObject)
            {
                PDImageXObject image = (PDImageXObject)pdImage;
                File file = new File(RESULT_FOLDER, String.format("10948-new-engine-%s-%s.%s", currentPage, index, image.getSuffix()));
                ImageIOUtil.writeImage(image.getImage(), image.getSuffix(), new FileOutputStream(file));
                index++;
            }
        }
        @Override
        public void appendRectangle(Point2D p0, Point2D p1, Point2D p2, Point2D p3) throws IOException { }
        @Override
        public void clip(int windingRule) throws IOException { }
        @Override
        public void moveTo(float x, float y) throws IOException {  }
        @Override
        public void lineTo(float x, float y) throws IOException { }
        @Override
        public void curveTo(float x1, float y1, float x2, float y2, float x3, float y3) throws IOException {  }
        @Override
        public Point2D getCurrentPoint() throws IOException { return null; }
        @Override
        public void closePath() throws IOException { }
        @Override
        public void endPath() throws IOException { }
        @Override
        public void strokePath() throws IOException { }
        @Override
        public void fillPath(int windingRule) throws IOException { }
        @Override
        public void fillAndStrokePath(int windingRule) throws IOException { }
        @Override
        public void shadingFill(COSName shadingName) throws IOException { }
    };
    pdfGraphicsStreamEngine.processPage(pdPage);
    page++;
}

(extractimage .java test method testExtractPageImages10948New)

此代码输出文件名为"10948-new-engine-1-0.tiff"、"10948-new-engine-2-0.tiff"、"10948-new-engine-3-0.tiff"one_answers"10948-new-engine-4-0.tiff"的图像,即每页一个。

PS:请记住在您的类路径中包含com.github.jai-imageio:jai-imageio-core,这是TIFF输出所必需的。

翻转图像

OP的另一个问题是图像有时出现颠倒,例如在他现在最新的示例文件"t1_edited.pdf"中。原因是这些图像确实是作为PDF中的图像资源颠倒存储的。

当这些图像被绘制到页面上时,当前有效的转换矩阵会镜像垂直绘制的图像,从而创建预期的外观。

通过稍微增强上面代码中的drawImage实现,可以在导出图像的名称中包含这种翻转的指示器:

public void drawImage(PDImage pdImage) throws IOException
{
    if (pdImage instanceof PDImageXObject)
    {
        Matrix ctm = getGraphicsState().getCurrentTransformationMatrix();
        String flips = "";
        if (ctm.getScaleX() < 0)
            flips += "h";
        if (ctm.getScaleY() < 0)
            flips += "v";
        if (flips.length() > 0)
            flips = "-" + flips;
        PDImageXObject image = (PDImageXObject)pdImage;
        File file = new File(RESULT_FOLDER, String.format("t1_edited-engine-%s-%s%s.%s", currentPage, index, flips, image.getSuffix()));
        ImageIOUtil.writeImage(image.getImage(), image.getSuffix(), new FileOutputStream(file));
        index++;
    }
}

现在垂直或水平翻转的图像会相应地被标记。

相关内容

  • 没有找到相关文章