4

我的目标是检索页面上所有单词的各自坐标,我所做的是

PdfReader reader = new PdfReader("cde.pdf");
TextWithPositionExtractionStategy S = new TextWithPositionExtractionStategy();
PdfTextExtractor.GetTextFromPage(reader,1,S);

Vector curBaseline = renderInfo.GetDescentLine().GetStartPoint();
Vector topRight = renderInfo.GetAscentLine().GetEndPoint();

iTextSharp.text.Rectangle rect = new iTextSharp.text.Rectangle(curBaseline[Vector.I1], curBaseline[Vector.I2], topRight[Vector.I1], topRight[Vector.I2]);
string x1 = curBaseline[Vector.I1].ToString();
string x2 = curBaseline[Vector.I2].ToString();
string x3 = topRight[Vector.I1].ToString();
string x4 = topRight[Vector.I2].ToString();

但是,我得到的是一个字符串的坐标,它包含一行的所有单词,而不是一个单词。例如pdf的内容是“我是女孩”,我得到的是“我是一个女孩”的坐标女孩”,但不是“i”“am”“a”“girl”的坐标。如何修改代码以便获得单词坐标。谢谢。

4

1 回答 1

8

(我主要使用 Java 库 iText,而不是 .Net 库 iTextSharp;因此,请忽略这里的一些 Java 主义,一切都应该易于翻译。)

RenderListener要使用 iText(Sharp) 提取页面的内容,您可以使用解析器包中的类在对您选择的 a 进行一些预处理后将其提供给它。

在您只对文本感兴趣的上下文中,您最常使用 aTextExtractionStrategy派生RenderListener并添加一个方法getResultantText来从页面中检索聚合文本。

由于 iText 中文本解析的最初意图是实现此用例,因此大多数现有RenderListener示例都是TextExtractionStrategy实现,并且仅使文本可用。

因此,您将不得不实施您自己的RenderListener,您似乎已经相信了TextWithPositionExtractionStategy

就像既有 a SimpleTextExtractionStrategy(通过对页面内容运算符的结构进行一些假设来实现)和 a LocationTextExtractionStrategy(没有相同的假设但稍微复杂一些),您可能希望从一个实现开始假设。

因此,就像在 的情况下一样SimpleTextExtractionStrategy,您在第一个简单的实现中期望转发给您的侦听器的文本呈现事件逐行到达,并且从左到右在同一行上。这样一来,一旦您发现水平间隙或标点,您就知道您当前的单词已经完成并且您可以对其进行处理。

与文本提取策略相比,您不需要StringBuffer成员来收集结果,而是需要一些“带有位置的单词”结构的列表。此外,您需要一些成员变量来保存TextRenderInfo您已经为此页面收集但最终无法处理的事件(您可以在几个单独的事件中检索一个单词)。

一旦你(即你的renderText方法)被调用一个新TextRenderInfo对象,你应该像这样操作(伪代码):

if (unprocessedTextRenderInfos not empty)
{
    if (isNewLine // Check this like the simple text extraction strategy checks for hardReturn
     || isGapFromPrevious) // Check this like the simple text extraction strategy checks whether to insert a space
    {
        process(unprocessedTextRenderInfos);
        unprocessedTextRenderInfos.clear();
    }
}

split new TextRenderInfo using its getCharacterRenderInfos() method;
while (characterRenderInfos contain word end)
{
    add characterRenderInfos up to excluding the white space/punctuation to unprocessedTextRenderInfos;
    process(unprocessedTextRenderInfos);
    unprocessedTextRenderInfos.clear();
    remove used render infos from characterRenderInfos;
}
add remaining characterRenderInfos to unprocessedTextRenderInfos;

process(unprocessedTextRenderInfos)你从 unprocessedTextRenderInfos 中提取你需要的信息;您将单个文本内容连接到一个单词并获取所需的坐标;如果您只想要起始坐标,您可以从第一个未处理的 TextRenderInfos 中获取这些坐标。如果您需要更多数据,您还可以使用来自其他 TextRenderInfo 的数据。使用这些数据,您可以填写“带有位置的单词”结构并将其添加到您的结果列表中。

页面处理完成后,您必须再次调用 process(unprocessedTextRenderInfos) 和 unprocessedTextRenderInfos.clear(); 或者,您可以在endTextBlock方法中执行此操作。

完成此操作后,您可能会觉得已经准备好实现稍微复杂一点的变体,它对页面内容结构没有相同的假设。;)

于 2012-12-05T09:29:51.640 回答