【问题标题】:Get the exact string position in PDF to be used later for changing it获取 PDF 中的确切字符串位置,以便稍后用于更改它
【发布时间】:2019-05-27 13:38:35
【问题描述】:

根据Get the exact Stringposition in PDF 问题的答案,我现在可以获取 PDF 文件中的所有字符串。请看代码:

PdfReader reader = new PdfReader("file.pdf");
RenderListener listener = new MyTextRenderListener();

PdfReaderContentParser parser = new PdfReaderContentParser(reader);
parser.processContent(1, listener);

static class MyTextRenderListener implements RenderListener {

        @Override
        public void renderText(TextRenderInfo renderInfo) {
            String text = renderInfo.getText(); // line with text
        }

        @Override
        public void beginTextBlock() { }

        @Override
        public void endTextBlock() { }

        @Override
        public void renderImage(ImageRenderInfo renderInfo) { }
}

mkl 在他的answer 中写道:

如果你的RenderListener除了检查文本 withgetText()也考虑getBaseline()or 甚至getAscentLine()andgetDescentLine().你拥有所有 您可能需要的坐标。

事实上,TextRenderInfo 有几个LineSegment 类的实例,它们给出了某种坐标。如何使用这些坐标(通过转换或从中提取适当的值)来准备 Rectangle 对象,以便可以删除找到的文本?一个矩形对象有四个坐标来描述给定文本的位置。

可以在 SO (Remove text occurrences contained in a specified area with iText ) 找到使用 Rectangle 对象删除字符串(即编辑)的示例

更新

我设法通过反复试验完成了我想做的事情,但我认为这是一种解决方法,而不是适当的解决方案。

@Override
public void renderText(TextRenderInfo renderInfo) {
    LineSegment baseline = renderInfo.getBaseline();
    float x = baseline.getStartPoint().get(Vector.I1);
    float y = baseline.getStartPoint().get(Vector.I2);
    float xx = baseline.getEndPoint().get(Vector.I1);
    float yy = baseline.getEndPoint().get(Vector.I2);
    rectangle = new Rectangle(x, yy, xx, y + 5);
}

现在我有一个 Rectangle 对象(请注意,我通过使用坐标将 5 添加到其坐标之一,以便它们覆盖所有字符串),我现在可以编辑文本。当没有图像时,它适用于单一颜色(例如白色)。当文本在图像上或页面颜色与黑色不同时,它将失败。这就是为什么我将我的解决方案描述为一种解决方法。 对我来说,最好将文本空白(用空字符串替换它)。如何做到这一点?

回复 mkl 的评论 不确定,如果我做得对:

LineSegment descentLine = renderInfo.getDescentLine();
float x = descentLine.getStartPoint().get(Vector.I1);
float y = descentLine.getStartPoint().get(Vector.I2);
float xx = descentLine.getEndPoint().get(Vector.I1);
float yy = descentLine.getEndPoint().get(Vector.I2);
rectangle = new Rectangle(xx, yy, x, y);

我也以同样的方式使用了 ascentLIne。不幸的是,这些都没有奏效。

【问题讨论】:

  • 你考虑过使用上升线和下降线的边界框吗?
  • @mkl 请查看我更新的帖子和我要问的稍微改变的问题。
  • 您使用基线并在其上方构建一个高度为 5 个单位的矩形。您是否考虑过使用上升线和下降线的边界框?
  • 我会试一试的。
  • @mkl 请看看我更新的帖子。

标签: java pdf itext


【解决方案1】:

在所有尝试中,您都尝试从一条线构造矩形,最初是基线,后来是下降线。使用这种方法,您显然没有矩形的高度,只能猜测。

您应该同时使用下降线和上升线!

例如假设文字直立的简化情况:

LineSegment ascentLine = renderInfo.getAscentLine();
LineSegment descentLine = renderInfo.getDescentLine();
float llx = descentLine.getStartPoint().get(Vector.I1);
float lly = descentLine.getStartPoint().get(Vector.I2);
float urx = ascentLine.getEndPoint().get(Vector.I1);
float ury = ascentLine.getEndPoint().get(Vector.I2);
rectangle = new Rectangle(llx, lly, urx, ury);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-05
    • 2012-05-27
    • 1970-01-01
    • 2020-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多