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のコンテンツは「私は女の子です」ですが、私が得たのは「私はgirl」ですが、「i」「am」「a」「girl」の座標ではありません。単語座標を取得できるようにコードを変更するにはどうすればよいですか。ありがとう。

4

1 に答える 1

8

(私は主に、.NetライブラリiTextSharpではなくJavaライブラリiTextを使用しています。したがって、ここでは一部のJavaイズムを無視してください。すべて、簡単に翻訳できるはずです。)

iText(Sharp)を使用してページのコンテンツを抽出するには、パーサーパッケージのクラスを使用して、前処理を行った後RenderListener、選択したページにフィードします。

テキストのみに関心があるコンテキストでは、最も一般的には、ページから集約されたテキストを取得するための単一のメソッドTextExtractionStrategyから派生し、追加するaを使用します。RenderListenergetResultantText

iTextでのテキスト解析の当初の目的はこのユースケースを実装することであったため、既存のRenderListenerサンプルのほとんどはTextExtractionStrategy実装であり、テキストのみを使用可能にします。

したがって、あなたはRenderListenerすでにあなたがキリスト教徒にしたように見えるあなた自身のものを実行しなければならないでしょうTextWithPositionExtractionStategy

SimpleTextExtractionStrategy(ページコンテンツ演算子の構造に関するいくつかの仮定で実装されている)とLocationTextExtractionStrategy(同じ仮定ではないがやや複雑な)の両方があるのと同じように、いくつかを作成する実装から始めたいと思うかもしれません仮定。

したがって、の場合と同様に、SimpleTextExtractionStrategy最初の単純な実装では、リスナーに転送されたテキストレンダリングイベントが1行ずつ、同じ行に左から右に到着することを期待しています。このようにして、水平方向のギャップまたは点を見つけるとすぐに、現在の単語が終了したことがわかり、それを処理できます。

テキスト抽出戦略とは対照的に、結果を収集するためにメンバーは必要ありませんが、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から必要な情報を抽出します。個々のテキストコンテンツを単語に連結し、必要な座標を取得します。開始座標が必要な場合は、未処理のTextRenderInfoの最初の座標から取得します。さらにデータが必要な場合は、他のTextRenderInfoのデータも使用します。これらのデータを使用して、「単語と位置」構造を入力し、結果リストに追加します。

ページ処理が終了したら、もう一度process(unprocessedTextRenderInfos)とunprocessedTextRenderInfos.clear()を呼び出す必要があります。または、メソッドでそれを行うこともできますendTextBlock

これを行うと、ページのコンテンツ構造に関して同じ仮定を持たない、もう少し複雑なバリアントを実装する準備ができていると感じるかもしれません。;)

于 2012-12-05T09:29:51.640 に答える