0

iTextsharpがpdfから画像を読み取ったり取得したりできない理由(msword、excel、powerpointから変換されたpdf)は非常に混乱しています

これが私がしたことです.mswordファイルを開き、mswordファイルをpdfに変換し、iTextsharpを使用してpdfファイルを読みましたが、pdfファイルに画像または形状があるかどうかを認識しません。

また、パワーポイントからpdfを試してから、pdfファイルを読みましたが、画像も読みません。

コードは次のとおりです。画像の下....編集済み...

これは抽出できない画像です。 ここに画像の説明を入力

これは私が少し前にテストした画像ですが、他の画像が検出されない、またはエラーになる理由がわかりません。 ここに画像の説明を入力

今のところ、コードを次のように変更しています。しかし、円形状の画像も検出できません。

    For pn As Integer = 1 To pc
        Dim pg As PdfDictionary = pdfr.GetPageN(pn)
        Dim res As PdfDictionary = DirectCast(PdfReader.GetPdfObject(pg.Get(PdfName.RESOURCES)), PdfDictionary)
        Dim xobj As PdfDictionary = DirectCast(PdfReader.GetPdfObject(res.Get(PdfName.XOBJECT)), PdfDictionary)

        MessageBox.Show("THE ERROR IS HERE, IT BYPASS, SO XOBJ IS NOTHING IN THAT IMAGE")

        If xobj IsNot Nothing Then
            For Each name As PdfName In xobj.Keys
                Dim obj As PdfObject = xobj.Get(name)
                If obj.IsIndirect() Then
                    Dim tg As PdfDictionary = DirectCast(PdfReader.GetPdfObject(obj), PdfDictionary)
                    Dim type As PdfName = DirectCast(PdfReader.GetPdfObject(tg.Get(PdfName.SUBTYPE)), PdfName)
                    Dim XrefIndex As Integer = Convert.ToInt32(DirectCast(obj, PRIndirectReference).Number.ToString(System.Globalization.CultureInfo.InvariantCulture))
                    Dim pdfObj As PdfObject = pdfr.GetPdfObject(XrefIndex)
                    Dim pdfStrem As PdfStream = DirectCast(pdfObj, PdfStream)
                    If PdfName.IMAGE.Equals(type) Then
                        Dim bytes As Byte() = PdfReader.GetStreamBytesRaw(DirectCast(pdfStrem, PRStream))
                        If (bytes IsNot Nothing) Then
                            Dim strat As New ImageInfoTextExtractionStrategy()
                            iTextSharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage(pdfr, pn, strat)
                        End If
                    End If
                End If
            Next
        End If
    Next
4

1 に答える 1

3

現在のコードがこれらの形状を検出または抽出しない理由:

スマイリー画像と花の画像は性質がまったく異なります。花の画像は、サブタイプ/Imageの/XObject ( eXternal Object )として PDF に保存されるビットマップ画像ですが、スマイリーは PDF に一部として保存されるベクター画像です。パス定義と描画操作の (必ずしも連続的ではない) シーケンスとしてのページ コンテンツ ストリームの。

あなたのコードは、外部オブジェクトとして保存されたビットマップ画像のみを検索し、やや複雑な方法で検索します。最初に低レベル メソッドを使用して画像 xobject をスキャンし、そのような xobject が見つかった場合にのみ、iText 高レベル抽出機能を使用します。iText 画像抽出機能のみを使用して開始した場合は、複雑さが軽減され、同時にインライン ビットマップ画像も認識されます。

iText in Action — 2nd Edition chapter 15 Webified iTextSharp Examples、特にMyImageRenderListener.csを利用するExtractImages.csを参照してください。そのコードからのインスピレーションは現在のコードを改善する可能性がありますが、まだ目前の問題を解決することにはなりません.

iText を使用して形状を検索または抽出するには、次のことを行う必要があります。

残念ながら、あなたの質問は、実際に達成しようとしていることについて完全に明確ではありません。

  1. ページに画像 (ビットマップまたはベクター グラフィック) があるかどうかを検出する必要があるだけですか?
  2. ページ上のサイズや位置など、画像に関する情報が必要ですか?
  3. それとも、実際に画像を抽出したいですか?

これらの目的は、前述の iText の高レベル抽出機能を使用してビットマップ グラフィックスで簡単に実装できますが、ベクター グラフィックスで実現するのはかなり困難です。

一般的な PDF の場合、個々の図の描画操作を一緒にする必要がないため、それらを実装することは実質的に不可能です。一見ランダムな順序で操作の 1 つの大きなヒープに混在します。

ただし、あなたの場合、利点が 1 つあります。Office は、PDF の図に適切にタグを付けているようです。これにより、ページ上のさまざまな (つまり、さまざまにタグ付けされた) ベクター グラフィックスの数の検出が少なくとも容易になり、また、どの描画操作がどの図に属しているかを区別することもできます。

したがって、ここでは、サンプル PDF のようにタグ付けされた PDF について上記の目標を達成する方法についていくつかの指針を示します。私自身は VB を使用していないため、サンプル コードはありません。しかし、サンプル コードは、オブジェクト参照に従う方法と PDF オブジェクト情報を解釈する方法を既に知っていることを示しているため、これらのポインタは方法を示すのに十分なはずです。

1.ページに画像があるかどうかを検出します。

ページ コンテンツがタグ付けされているので、ドキュメント カタログの/StructTreeRootPdfReader.Catalog,エントリから始まる構造階層をスキャンするだけで十分です (その中の値を選択してPdfName.STRUCTTREEROOT掘り下げます)。

たとえば、サンプルのページ 1 (PDF オブジェクト 4 0) (上部に「1233」、下部にスマイリー) の場合、辞書を含む配列が見つかります。

<<
  /Pg 4 0 R
  /K [0]
  /S /P
  /P 24 0 R
>>

<<
  /Pg 4 0 R
  /K [1]
  /Alt   ()
  /S /Figure
  /P 22 0 R
>>

それぞれがページ ( /Pg 4 0 R) を参照しています。最初のものはタイプ/P段落(「1233」) であり、2 つ目はタイプ/Figure(スマイリー) です。2 番目の要素の存在は、ページに図が存在することを示します。したがって、目標 1 はこれらのデータですでに達成されています。

(詳細については、PDF 仕様ISO 32000-1:2008セクション 14.7 および 14.8 を参照してください。)

2. サイズやページ上の位置など、画像に関する情報を取得します。

このためには、問題の図の作成を担当するグラフィックス オペレータを抽出する必要があります。/K [1]タグ付けされているので、上記の/Figureディクショナリで指定されたマークされたコンテンツ ID (つまり1 )に関連付けられたマークされたコンテンツ ブロック内の演算子を抽出する必要があります。

コンテンツ ストリームには、次のようなものがあります。

/P <</MCID 1>> BDC 0.31 0.506 0.741 rg
108.6 516.6 m
108.6 569.29 160.18 612 223.8 612 c
287.42 612 339 569.29 339 516.6 c
339 463.91 287.42 421.2 223.8 421.2 c
160.18 421.2 108.6 463.91 108.6 516.6 c
h
f*
[...]
108.6 516.6 m
108.6 569.29 160.18 612 223.8 612 c
287.42 612 339 569.29 339 516.6 c
339 463.91 287.42 421.2 223.8 421.2 c
160.18 421.2 108.6 463.91 108.6 516.6 c
h
S
EMC

/MCID 1のBDCEMCの間のこのセクションには、求めるグラフィック操作が含まれています。それらが表す図に関する情報を取得したい場合は、それらを分析する必要があります。

これは、これらすべてに関する非常に低レベルのビューであり、これを取得するには高レベルの API が必要な場合があります。

parseriText には、名前空間クラスPdfReaderContentParserを使用したテキストおよびビットマップ画像処理の類似操作のための高レベル API がありRenderListenerImageInfoTextExtractionStrategy.残念ながら、PdfReaderContentParserベクター グラフィックス関連の演算子を適切に前処理していません。

したがって、iText でこれを行うには、基礎となるものを拡張しPdfContentStreamProcessorて不足している前処理を追加する必要があります (パーサー クラスは個々の操作に対して個別のリスナーを使用して実装され、新しいリスナーを簡単に登録できるため実行可能です)。グラフィックオペレータ); または、ページのコンテンツを取得して自分で解析する必要があります。

3. 画像を抽出します。

PDF 内のベクター画像は PDF 固有のベクター グラフィック オペレーターを使用するため、最初に画像をエクスポートする形式を決定する必要があります。生の PDF 演算子に関心がない限り、目的の形式でファイルを作成するのに役立つライブラリが必要になる可能性が高くなります。

それが決定されたら、まず前に説明したように問題のグラフィックス オペレータを抽出し、次にそれらをそのライブラリにフィードして、選択したエクスポート可能なイメージを作成します。

于 2013-06-24T10:56:25.123 に答える