代码之家  ›  专栏  ›  技术社区  ›  menteith

获取PDF中的确切字符串位置,以便以后更改它

  •  1
  • menteith  · 技术社区  · 6 年前

    根据问题的答案 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) { }
    }
    

    百万分之一 在他的 answer 写的:

    如果你 RenderListener 除了检查文本 具有 getText() 也考虑 getBaseline() 或 即使 getAscentLine() getDescentLine(). 你拥有所有 您可能需要的坐标。

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

    使用矩形对象删除字符串(即redacting)的示例可以在so中找到( Remove text occurrences contained in a specified area with iText )

    更新

    我通过尝试和错误成功地做到了我想要的,但我认为这是一个解决方法,而不是一个合适的解决方案。

    @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);
    }
    

    现在我有了一个矩形对象(注意,我通过使用坐标向其中一个坐标添加了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);
    

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

    1 回复  |  直到 6 年前
        1
  •  0
  •   mkl    6 年前

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

    相反,你应该同时利用下降线和上升线!

    例如,假设文本垂直绘制的简化情况:

    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);