【问题标题】:PDFBox text extraction, rotation and font name, sizePDFBox 文本提取、旋转和字体名称、大小
【发布时间】:2018-07-30 08:02:43
【问题描述】:

我正在使用最新的 PDFBOX 库来提取文本,为了做到这一点,我编写了我的自定义 PDFStreamEngine(显示部分代码,但其余部分应该类似):

else if ("Tf".equals(operation) && parsingTextObject) {
            if (operands.size() < 2) {
                throw new MissingOperandException(operator, operands);
            }

            COSBase base0 = operands.get(0);
            COSBase base1 = operands.get(1);
            if (!(base0 instanceof COSName)) {
                return;
            }
            if (!(base1 instanceof COSNumber)) {
                return;
            }
            COSName fontName = (COSName) base0;
            float fontSize = ((COSNumber) base1).floatValue();
            getGraphicsState().getTextState().setFontSize(fontSize);
            PDFont font = getResources().getFont(fontName);
            getGraphicsState().getTextState().setFont(font);
}

但是,我遇到了 3 个问题: 第一个:“Tf”运算符 - 在 PDF /F1 1 Tf 中:当我显示 fontName 和 size 时,它​​显示:EVMANJ+MyriadPro-Regular, size 1;但是,illustrator 和 adobe acrobat 上的实际字体名称:Myriad Pro, size 8 pt

第二题:如图所示文字是垂直的,如何提取文字的旋转?

第三题:如何正确对待TJ算子?

P.S:我可以私下提供pdf。

【问题讨论】:

  • 1) 这是一个子集,size 1表示Adobe在Tf命令中直接使用了比例而不是8; 2)当前转换矩阵/文本矩阵 3)我不明白这个问题 - 也许看看 PDF 32000 规范?还可以查看源代码下载中的 PrintTextLocations 示例和 TextPosition 对象。还可以使用 PDFDebugger 查看您的文件,然后查看内容流。
  • @TilmanHausherr 非常感谢,PrintTextLocations 是一个很好的例子,但是,我已经在扩展 PDFStreamEngine 并且我需要坚持使用它,是否有一种方法可以覆盖执行与 writeString 类似的功能?
  • 我无法回答这个问题,因为我对您的代码了解得不够多,而且我从未扩展过 PDFStreamEngine(可能在复制和粘贴代码中除外)。然而,我提到的那个例子扩展了 PDFTextStripper,它扩展了 LegacyPDFStreamEngine。它扩展了 PDFStreamEngine。

标签: pdf pdfbox


【解决方案1】:

这个问题的答案并不直接,我不得不扩展 showFontGlyph

protected void showFontGlyph(Matrix textRenderingMatrix, PDFont font, int code, String unicode, Vector displacement) throws IOException {
..do you logic here}

为了找到旋转,我不得不将 PDFBox 1.8 中的代码复制粘贴到我的班级中

/**
 * Return the direction/orientation of the string in this object based on
 * its text matrix.
 * 
 * @return The direction of the text (0, 90, 180, or 270)
 */
public int getDir() {
    int direction = -1;
    if (direction < 0) {
        float a = getTextMatrix().getScaleY();
        float b = getTextMatrix().getShearY();
        float c = getTextMatrix().getShearX();
        float d = getTextMatrix().getScaleX();
        // 12 0 left to right
        // 0 12
        if (a > 0 && Math.abs(b) < d && Math.abs(c) < a && d > 0) {
            direction = 0;
        }
        // -12 0 right to left (upside down)
        // 0 -12
        else if (a < 0 && Math.abs(b) < Math.abs(d) && Math.abs(c) < Math.abs(a) && d < 0) {
            direction = 180;
        }
        // 0 12 up
        // -12 0
        else if (Math.abs(a) < Math.abs(c) && b > 0 && c < 0 && Math.abs(d) < b) {
            direction = 90;
        }
        // 0 -12 down
        // 12 0
        else if (Math.abs(a) < c && b < 0 && c > 0 && Math.abs(d) < Math.abs(b)) {
            direction = 270;
        } else {
            direction = 0;
        }
    }
    return direction;
}

当我在处理流时检测到 TJ 运算符时,我会调用 getDir 函数。

【讨论】:

  • 您的getDir 只返回 90° 的倍数,但可以以任意角度绘制文本。
  • @mkl 没错,幸运的是,我正在处理的案例只有 4 个角度:0、90、180、270。这是我使用 PDFBox 2.0.x 找到的唯一可行的解​​决方案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-25
相关资源
最近更新 更多