使用itextsharp检索页面上所有单词的相应坐标

时间:2012-12-05 00:51:06

标签: c# itextsharp

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

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的内容是“我是一个女孩”,我得到的是“我是一个女孩“,但不是”我“”是“”一个“”女孩“的坐标。如何修改代码,以便我可以得到单词坐标。感谢。

1 个答案:

答案 0 :(得分:8)

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

为了使用iText(夏普)提取页面内容,您可以使用解析器包中的类在经过一些预处理后将其提供给您选择的RenderListener

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

由于iText中文本解析的初始目的是实现此用例,因此大多数现有RenderListener示例都是TextWithPositionExtractionStategy实现,只能使文本可用。

因此,您必须实施自己的SimpleTextExtractionStrategy,而您似乎已经使用了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)对象,就应该像这样操作(伪代码):

endTextBlock

在{{1}}中,您从unprocessedTextRenderInfos中提取所需的信息;将单个文本内容连接到一个单词并获取所需的坐标;如果你只想要开始坐标,你可以从第一个未经处理的TextRenderInfos中获取。如果您需要更多数据,还可以使用其他TextRenderInfos中的数据。使用这些数据,您可以在#34;中填写一个"字。结构并将其添加到结果列表中。

页面处理完成后,您必须再次调用进程(unprocessedTextRenderInfos)和unprocessedTextRenderInfos.clear();或者你可以用{{1}}方法做到这一点。

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