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

che*_*hai 3 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();
Run Code Online (Sandbox Code Playgroud)

但是,我得到的是一个字符串的坐标,它包含一行的所有单词,而不是一个单词.例如,pdf的内容是"我是一个女孩",我得到的是"我是一个"的坐标女孩",但不是"我""是""""女孩"的坐标.如何修改代码,以便我可以得到单词坐标.谢谢.

mkl*_*mkl 8

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

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

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

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

因此,您必须实施自己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;
Run Code Online (Sandbox Code Playgroud)

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

页面处理完成后,您必须再次调用进程(unprocessedTextRenderInfos)和unprocessedTextRenderInfos.clear(); 或者你可以在endTextBlock方法中这样做.

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