6

このPDFをWordファイルに変換するC#でitextsharpを使用してこのPDFを読み込もうとしています。また、英語のpdfを試したときに単語の表の書式設定とフォントを維持する必要があります。完全に機能しますが、ヒンディー語、マラーティー語などのインドの言語の一部を使用すると機能しません。

 public string ReadPdfFile(string Filename)
        {

            string strText = string.Empty;
            StringBuilder text = new StringBuilder();
            try
            {
                PdfReader reader = new PdfReader((string)Filename);
                if (File.Exists(Filename))
                {
                    PdfReader pdfReader = new PdfReader(Filename);

                    for (int page = 1; page <= pdfReader.NumberOfPages; page++)
                    {                        ITextExtractionStrategy strategy = new SimpleTextExtractionStrategy();
                        string currentText = PdfTextExtractor.GetTextFromPage(pdfReader, page, strategy);

                        text.Append(currentText);
                        pdfReader.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            textBox1.Text = text.ToString();
            return text.ToString(); ;
        }
4

2 に答える 2

16

ドキュメント ページの一番上の行で、サンプルの「मतद|र」が「मतदरर」として抽出されていることに特に焦点を当ててファイルを調べました。

手短に:

ドキュメント自体が情報を提供します。たとえば、見出し行のグリフ「मतद|र」はテキスト「मतदरर」を表します。文書のソースに、フォント情報が誤解を招かないバージョンの文書を問い合わせる必要があります。それが不可能な場合は、OCR を使用する必要があります。

詳細に:

最初のページの先頭行は、ページ コンテンツ ストリームの次の操作によって生成されます。

/9 280 Tf
(-12"!%$"234%56*5) Tj

最初の行は、 /9という名前のフォントを 280 のサイズで選択します (ページの最初の操作により、すべてが 0.05 倍に拡大されます。したがって、有効なサイズは、ファイルで観察される 14 単位です)。

2 行目では、グリフが印刷されます。これらのグリフは、そのフォントのカスタム エンコーディングを使用して括弧内で参照されます。

プログラムがテキストを抽出しようとするとき、フォントからの情報を使用して、これらのグリフ参照から実際の文字を推測する必要があります。

PDF の最初のページのフォント/9は、次のオブジェクトを使用して定義されます。

242 0 obj<<
    /Type/Font/Name/9/BaseFont 243 0 R/FirstChar 33/LastChar 94
    /Subtype/TrueType/ToUnicode 244 0 R/FontDescriptor 247 0 R/Widths 248 0 R>>
endobj
243 0 obj/CDAC-GISTSurekh-Bold+0
endobj 
247 0 obj<<
    /Type/FontDescriptor/FontFile2 245 0 R/FontBBox 246 0 R/FontName 243 0 R
    /Flags 4/MissingWidth 946/StemV 0/StemH 0/CapHeight 500/XHeight 0
    /Ascent 1050/Descent -400/Leading 0/MaxWidth 1892/AvgWidth 946/ItalicAngle 0>>
endobj 

したがって、/Encoding要素はありませんが、少なくとも/ToUnicodeマップへの参照があります。したがって、テキストを抽出するプログラムは、指定された/ToUnicodeマッピングに依存する必要があります。

/ToUnicodeによって参照されるストリームには、(-12"!%$"234%56*5) からテキストを抽出するときに、次の重要なマッピングが含まれています。

<21> <21> <0930>
<22> <22> <0930>
<24> <24> <091c>
<25> <25> <0020>
<2a> <2a> <0031>
<2d> <2d> <092e>
<31> <31> <0924>
<32> <32> <0926>
<33> <33> <0926>
<34> <34> <002c>
<35> <35> <0032>
<36> <36> <0030>

(すでにここで、複数の文字コードが同じ Unicode コード ポイントにマッピングされていることがわかります...)

したがって、テキスト抽出の結果は次のようになります。

- = 0x2d -> 0x092e = म
1 = 0x31 -> 0x0924 = त
2 = 0x32 -> 0x0926 = द
" = 0x22 -> 0x0930 = र    instead of  |
! = 0x21 -> 0x0930 = र
% = 0x25 -> 0x0020 =  
$ = 0x24 -> 0x091c = ज
" = 0x22 -> 0x0930 = र
2 = 0x32 -> 0x0926 = द
3 = 0x33 -> 0x0926 = द
4 = 0x34 -> 0x002c = ,
% = 0x25 -> 0x0020 =  
5 = 0x35 -> 0x0032 = 2
6 = 0x36 -> 0x0030 = 0
* = 0x2a -> 0x0031 = 1
5 = 0x35 -> 0x0032 = 2

したがって、ドキュメントの最初のページの見出しから iTextSharp (および Adob​​e Reader も!) が抽出したテキストは、ドキュメントが主張するフォント情報が正しいものとまったく同じです。

この原因は、フォント定義の誤解を招くマッピング情報にあるため、ドキュメント全体に誤解を招く解釈があることは驚くべきことではありません。

于 2013-03-22T09:27:27.880 に答える
4

@mklが言ったように、物事が機能しない理由についての詳細情報が必要になります。しかし、私はあなたに役立つかもしれないいくつかのことをあなたに話すことができます。

まず、非常に簡単SimpleTextExtractionStrategyです。そのためのドキュメントを読むと、次のことがわかります。

PDFが上から下以外の方法でテキストをレンダリングする場合、その結果、テキストはPDFでの表示方法を正確に表していないことになります。

つまり、PDFは上から下に読む必要があるように見えるかもしれませんが、異なる順序で書かれている可能性があります。参照したPDFには、実際には2番目の視覚的な線が最初に書かれています。テキストを上から下に戻そうとする少し賢いテキスト抽出戦略については、ここにある私の投稿を参照してください。PDFの最初のページに対してコードを実行すると、各「行」が正しく引き出されているように見えます。

第二に、PDFにはテーブルの概念がありません。特定の場所にテキストと線が描かれているだけで、どちらも相互に関連していません。つまり、すべての行を計算し、独自のテーブルの概念を構築する必要があります。これを行うコードはiTextSharp内にありません。個人的には、わざわざ書き込もうとはしませんでした。

第三に、テキスト抽出は、フォントとは関係のないテキストをプルするためのものです。それが必要な場合は、自分でそのロジックを構築する必要があります。非常に基本的なスタートについては、こちらの投稿をご覧ください。

于 2013-03-13T14:11:18.643 に答える