当前位置: 首页 > 知识库问答 >
问题:

Apache PDFBox-图像和文本位置之间的垂直匹配

慎弘化
2023-03-14

我需要帮助来实现PDF文档中文本和图像html" target="_blank">对象之间的映射。

如第一幅图所示,我的PDF文档中有3幅图像沿y方向随机排列。在它们的左边是文本。文本沿着图像的高度延伸。

我的目标是将文本合并到“ImObj”对象中(请参见ImObj类)。

第2张图显示,我想使用图像的高度来检测文本的位置(图像高度之外的所有文本都应忽略),在示例中,将有3个由3个图像形成的ImObj-对象。

pdf文件的链接位于此处(在WetTransfer上):[在此处输入链接描述][3]

但是我的映射不起作用,因为我可能使用了图像中的错误坐标。现在我已经看了一些例子,但我仍然不太明白如何获得文本和图像一起工作的坐标?这是我的代码:

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.pdfbox.contentstream.operator.Operator;
import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.graphics.PDXObject;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.text.PDFTextStripper;
import org.apache.pdfbox.text.TextPosition;
import org.apache.pdfbox.util.Matrix;

public class ImExample extends PDFTextStripper {

    public static void main(String[] args) {
        File file = new File("C://example document.pdf");

        try {
            PDDocument document = PDDocument.load(file);

            ImExample example = new ImExample();

            for (int pnr = 0; pnr < document.getPages().getCount(); pnr++) {
                PDPage page = document.getPages().get(pnr);
                PDResources res = page.getResources();
            
                example.processPage(page);
             
                int idx = 0;

                for (COSName objName : res.getXObjectNames()) {
                    PDXObject xObj = res.getXObject(objName);
                    if (xObj instanceof PDImageXObject) {

                        System.out.println("...add a new image");

                        PDImageXObject imXObj = (PDImageXObject) xObj;
                        BufferedImage image = imXObj.getImage();

                        // Here is my mistake ... but I do not know how to solve it.
                        ImObj imObj = new ImObj(image, idx++, pnr, image.getMinY(), image.getMinY() + image.getHeight());
                        example.imObjects.add(imObj);
                    }
                } 
            }

            example.setSortByPosition(true);
            example.getText(document);

            // Output
            for (ImObj iObj : example.imObjects)
                System.out.println(iObj.idx + " -> " + iObj.text);

            document.close();

        } catch (Exception e) {
            e.printStackTrace();
        } 
    }

    public List<ImObj> imObjects = new ArrayList<ImObj>();

    public ImExample() throws IOException {
        super();
    }

    @Override
    protected void writeString(String text, List<TextPosition> textPositions) throws IOException {

        // match between imagesize and textposition
        TextPosition txtPos = textPositions.get(0);

        for (ImObj im : imObjects) {
            if(im.page == (this.getCurrentPageNo()-1))
                if (im.minY < txtPos.getY() && (txtPos.getY() + txtPos.getHeight()) < im.maxY)
                    im.text.append(text + " "); 
        }
    }
}

class ImObj {

    float minY, maxY;

    Image image = null;
    StringBuilder text = new StringBuilder("");
    int idx, page = 0;

    public ImObj(Image im, int idx, int pnr, float yMin, float yMax) {
        this.idx = idx;
        this.image = im;
        this.minY = yMin;
        this.maxY = yMax;
        this.page = pnr;
    } 
}

顺致敬意,

共有1个答案

邢飞鸿
2023-03-14

你在(有点)错误的地方寻找图像!

您遍历页面本身的图像XObject资源并检查它们。但这没有帮助:

>

还有其他地方可以在页面上存储和使用图像,例如在页面上使用的某种形式的XObject或模式的资源中,或在内容流中内联。

您实际需要的是解析页面内容流以使用图像和使用时的当前转换矩阵。有关基本实现,请查看PDFBox示例PrintImageLocations

您将遇到的下一个问题是PDFBox在TextPotion方法getXgetY中返回的坐标不是来自相关PDF页面的原始坐标系,而是来自一些为了在文本提取代码中更容易处理而归一化的坐标系。因此,您很可能应该使用未归一化的坐标。

你可以在这个答案中找到相关信息。

 类似资料:
  • 我检查了一个相关的问题,我看到新行的语法是: 但是,我不知道如何将其添加到我的网站代码中: 这是我的网站,我想做的是把文字放在图片的“潜行峰”在一个新的行。 非常感谢:)

  • 问题内容: 我有一个包含图像和ap标签的div(如下所示)。我想根据段落的多少行在div的中间垂直对齐图像。垂直对齐不起作用。我现在正在使用JavaScript找出要添加到margin- top的数量,但是宁愿使用CSS。有任何想法吗? 问题答案: 尝试将元素的属性设置为图像的高度,例如: 编辑: 刚意识到我读错了问题,却错过了多行的事实。尝试的一种选择是完全删除元素,并将其设置为of的,使用的o

  • 我对Vertx中的标准顶点和工人顶点感到困惑。它们的用例是什么?

  • 注:这是一个关于现代正则表达式口味可能性的问题。这不是用其他方法解决这个问题的最佳方法。它受到了前面一个问题的启发,但这个问题并不局限于正则表达式。 在ASCII“image”/art/map/string格式中: 我想找到三个s组成的简单垂直线: 图像中的行数是可变的,每行的宽度也是可变的。 使用正则表达式(PCRE/PHP, Perl,.NET或类似)是否有可能: 确定是否存在此类地层

  • 问题内容: 注意:这是有关现代正则表达式口味的问题。这不是使用其他方法解决此问题的最佳方法。它是由一个较早的问题启发而来的,但是这个问题并不局限于正则表达式。 问题 在ASCII“图像” /艺术/地图/字符串中,例如: 我想找到一个简单的垂直线3 s: 图像中的行数是可变的, 每 行的宽度也是可变的。 问题 使用正则表达式(PCRE / PHP,Perl,.NET或类似文件)可以: 确定是否存在这

  • 问题内容: 我是eclipse IDE的新手。 我们可以在Eclipse中为Java编辑器执行以下操作吗? 如何在Eclipse中配置它以显示Java编辑器中匹配的花括号之间的垂直线?可能吗? 问题答案: 我可以建议的最接近的解决方案是: 单击Eclipse IDE>窗口>首选项>常规>编辑器>文本编辑器 然后单击链接“空白字符”以指定应显示的内容。 然后,仅对Tab启用复选框“ Leading