【问题标题】:Pdfbox PDFTextStripperByArea coordinates shiftedPdfbox PDFTextStripperByArea 坐标偏移
【发布时间】:2012-01-04 13:09:38
【问题描述】:

我遇到了坐标问题。 PDFTextStripperByArea 区域似乎被推得太高了。

考虑以下示例 sn-p:

...
PDPage page = (PDPage) allPages.get(0);
PDFTextStripperByArea stripper = new PDFTextStripperByArea();

// define region for extraction -- the coordinates and dimensions are x, y, width, height
Rectangle2D.Float region = new Rectangle2D.Float(x, y, width, height);
stripper.addRegion("test region", region);

// overlay the region with a cyan rectangle to check if I got the coordinates and dimensions right 
PDPageContentStream contentStream = new PDPageContentStream(document, page, true, true);
contentStream.setNonStrokingColor( Color.CYAN );
contentStream.fillRect(x, y, width, height );
contentStream.close();

// extract the text from the defined region
stripper.extractRegions(page);
String content = stripper.getTextForRegion("test region"); 
... 
document.save(...); ...

青色矩形很好地覆盖了所需区域。另一方面,stripper 遗漏了矩形底部的几行,并在矩形上方包含了几行——看起来它“向上”移动(按 y 坐标)。到底是怎么回事?

【问题讨论】:

    标签: pdfbox


    【解决方案1】:

    正如 Christian 在评论中所说,问题在于 fillRect() 方法的坐标系和 PDFTextStripperByArea 的坐标系不同。

    第一个期望原点是页面的左下角,而第二个期望它是左上角。

    因此,要使其正常工作,请将赋予 PDFTextStripperByArea 的区域更改为:

    Rectangle2D.Float region = new Rectangle2D.Float(x, ph - y - height, width, height);
    

    其中 ph 是页面高度:

    float ph = page.getMediaBox().getUpperRightY();
    

    PS:我知道这是一个很老的问题,但是当我遇到同样的问题时,Google 把我带到了这里,所以我会添加我的答案。

    【讨论】:

    • “第一个期望原点是页面的左下角” - 更准确地说:它期望由裁剪框/媒体框定义的坐标。媒体框经常的原点位于左下角,但并非总是。因此,通用解决方案也相应地翻译 x
    【解决方案2】:

    文本通常包含在定位矩形内。有时,文本不在该矩形内的预期位置,PDFBox 使用该矩形尝试猜测文本的位置。因此,如果文本从捕获区域之外开始并流入其中,则可能不会被提取。

    粗略的草图:文本框在捕获区域之外开始,但文本在其中流动。它可能不会被捕获。

    ____________
    |Page      |
    |   _______|
    |   |Area ||
    |   |     ||
    | ..|.....||
    | ⁞ |Text⁞||
    | ⁞ |____⁞||
    | ⁞......⁞ |
    |__________|
    

    【讨论】:

    • 您好,我遇到了几乎相同的问题:我从 PDF 文档中提取块,并希望根据它们的坐标绘制矩形。我得到了正确的宽度和高度,但正如你所提到的,最终的矩形是垂直移动的:块的第一行不包含在矩形中。有什么技巧可以避免吗?
    • @NicolasW。 Pdfbox 在猜测文本实际位置而不是开始位置时存在问题 - 因此,如果您的文本从矩形外部开始并在其中流动,则可能无法捕获它。诀窍是尝试稍大的捕获区域,以便捕获从当前捕获区域之外开始的文本。我没有发现比这更聪明的东西了。
    • 注意 Rectangle2D.Float() 期望 x 和 y 是左上角坐标,而 PDPageContentStream 的 fillRect() 方法期望左下角坐标
    • 并且 PDPageContentStream 需要与文档左下角原点的坐标。
    猜你喜欢
    • 2012-01-20
    • 2014-01-11
    • 2011-12-20
    • 2021-08-07
    • 2018-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多