用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();
但是,我得到的是一个string的坐标,其中包含一行,而不是一个单词的所有单词。例如,pdf的内容是“我是一个女孩”,我得到的是“我是一个女孩“,而不是”我“,”我“,”一个“,”女孩“的坐标。我如何修改代码,以便我可以获得单词坐标。 谢谢。
(我主要使用Java库iText,而不是使用.Net库iTextSharp;因此,请忽略一些Java-isms,一切都应该很容易翻译。)
为了使用iText(Sharp)提取页面的内容,您可以使用parsing器包中的类在预处理之后将其RenderListener
给您所select的RenderListener
。
在只对文本感兴趣的上下文中,通常使用从RenderListener
派生的TextExtractionStrategy
,并添加一个方法getResultantText
来检索页面中的聚合文本。
由于iText中文本parsing的最初意图是实现这个用例,所以大多数现有的RenderListener
示例都是TextExtractionStrategy
实现,只能使文本可用。
因此,你将不得不实现你自己的RenderListener
,你似乎已经基本RenderListener
。
就像同时存在一个SimpleTextExtractionStrategy
(它是通过关于页面内容操作符的结构的一些假设来实现的)和一个LocationTextExtractionStrategy
(它没有相同的假设但有些复杂),您可能需要从一个实现开始做出一些假设。
因此,就像SimpleTextExtractionStrategy
的情况一样,在第一个简单的实现中,您希望将文本呈现事件转发给您的侦听器,从一行一行到另一行,从左到右。 这样,只要你find一个横向的差距或标点符号,你就知道你当前的单词已经完成,你可以处理它。
与文本提取策略相反,您不需要一个StringBuffer
成员来收集结果,而是需要一个“有位置的词”结构的列表。 此外,您需要一些成员variables来保存已经为此页面收集的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中获取坐标。 如果您需要更多的数据,您还可以使用其他TextRenderInfos中的数据。 有了这些数据,你可以填写一个“有位置的单词”结构,并将其添加到结果列表中。
当页面处理完成后,你必须再次调用进程(unprocessedTextRenderInfos)和unprocessedTextRenderInfos.clear(); 或者你可以在endTextBlock
方法中做到这endTextBlock
。
做完这些之后,你可能会觉得可以实现稍微复杂的变体,这个变体对页面内容结构没有相同的假设。 ;)