C# 使用itextsharp检索页面上所有单词的各自坐标

C# 使用itextsharp检索页面上所有单词的各自坐标,c#,itextsharp,C#,Itextsharp,我的目标是检索页面上所有单词的各自坐标,我所做的是 PdfReader reader = new PdfReader("cde.pdf"); TextWithPositionExtractionStategy S = new TextWithPositionExtractionStategy(); PdfTextExtractor.GetTextFromPage(reader,1,S); Vector curBaseline = renderInfo.GetDescentLine().GetS

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

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

(我主要使用Java库iText,而不是.Net库iTextSharp;因此,请忽略这里的一些Java ISM,所有内容都应该很容易翻译。)

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

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

由于iText中文本解析的最初目的是实现这个用例,因此大多数现有的
RenderListener
示例都是
textextextractionstrategy
实现,并且只提供文本

因此,您必须实现自己的
RenderListener
,您似乎已经将其命名为
TextWithPositionExtractionStategy

就像有一个
SimpleTextExtractionsStrategy
(通过对页面内容操作符的结构进行一些假设来实现)和一个
LocationTextExtractionsStrategy
(没有相同的假设,但有点复杂),您可能希望从一个做出一些假设的实现开始

因此,就像在
simpletextractionstrategy
中一样,在第一个简单的实现中,您希望转发给侦听器的文本呈现事件逐行到达,并从左到右到达同一行。这样,一旦你发现一个水平缺口或穿孔,你就知道你的当前单词已经完成了,你可以处理它

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

一旦为新的
TextRenderInfo
对象调用了您的
renderText
方法,您应该像这样操作(伪代码):

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

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


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

一个词就是一个字符串。准确地向我们展示您得到的内容,并将其与您想要的内容进行比较。PDF中的文本段不一定在单词边界处开始或停止。因此,您必须拆分或合并文本段。@mkl,谢谢,我知道您说什么,但我不知道怎么做。您能给我更多的帮助吗?可能会重复Hi!我遵循了这个解决方案,我“几乎”得到了它,除了我正在绞尽脑汁试图在初始块的矩形内获得每个特定单词的坐标(矩形本身)。有没有“简单”的方法来实现这一点?事实上,我正在提取文本块中的每个单词,并根据实际的左、右等来计算坐标。我这样做对吗?非常感谢你的解释@Gonzo345您考虑过使用getCharacterRenderInfo()方法拆分新TextRenderInfo的步骤吗?在这一步中,对于每个glyph,您会得到一个
TextRenderInfo
,特别是对于每个以单词开头或结尾的glyph。如果您已经考虑过这一点,但仍然没有取得进展,请创建一个实际的堆栈溢出问题,提供足够的代码和一个示例文档来重现该问题。
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;