0

iText 5.0.1 を使用して既存の PDF を操作しています。RUPSを使用して既存の PDF を分析すると、最初のページに /Resources が含まれていることがわかります。

ここに画像の説明を入力

ただし、次の例を使用して PDF を操作すると、 pageDictionary.get(PdfName.RESOURCES)が null を返すため、NPE が発生します。

デバッグ時にpageDictionnaryオブジェクトに含まれるものは次のとおりです。

ここに画像の説明を入力

残念ながら、機密保持のため、現在 PDF を投稿することはできませんが、なぜこの NPE を取得しているのかわかる人はいますか? または、さらに調査する方法を知っている人はいますか? (私は iText と PDF 構造の専門家にはほど遠いです...そしてゆっくりと考えを失いつつあります)

どうもありがとうございました !

4

1 に答える 1

4

使用するサンプル コードは、 PageオブジェクトがPagesカタログ キーによって指されるディクショナリの直接の子であることを前提としています。

PdfDictionary pages = (PdfDictionary) PdfReader.getPdfObject(reader.getCatalog().get(PdfName.PAGES));
PdfArray kids = (PdfArray) PdfReader.getPdfObject(pages.get(PdfName.KIDS));
PdfDictionary pageDictionary = (PdfDictionary) PdfReader.getPdfObject((PdfObject) kids.getArrayList().get(pageNum - 1));

多くの PDF プロデューサは単純なページ ツリーを生成するため、この仮定はしばしば問題ありませんが、一般的に、ページ ツリーは実際には 1 よりも大きな深さを持つツリーある可能性があります。ルートPagesディクショナリの kids of kidsなど。

PDF の場合、ページ 1 (オブジェクト 3)のPageディクショナリは、ルートPagesディクショナリ オブジェクト 70の子供であるPagesディクショナリ オブジェクト 6 の子供です。

したがって、そのコードは、中間のPagesディクショナリ オブジェクト 6 がすでにPageオブジェクトであると想定しています。

ただし、サンプル コードの問題はこれだけではありません。たとえば、 ResourcesディクショナリがPageオブジェクト自体に関連付けられていることも前提としています。これは真である必要はありません。ページ ツリー ルートを含む任意の親Pagesオブジェクトにアタッチされている場合もあります。

リソースディクショナリ(必須、継承可能)ページに必要なリソースを含むディクショナリ (7.8.3「リソース ディクショナリ」を参照)。ページがリソースを必要としない場合、このエントリの値は空の辞書になります。エントリを完全に省略すると、リソースがページ ツリーの祖先ノードから継承されることを示します。

(表 30 – ページ オブジェクトのエントリ - ISO 32000-1、現在の PDF 仕様)

したがって、一般的に使用するサンプルは、PDF 仕様を尊重しないため役に立ちません。


そうは言っても、あなたのサンプルは、iText 5.0.1 を使用しているときに iText の最新バージョン1.02bだったときのものです...なぜ、より最新のサンプルを探さなかったのですか? 4 つのメジャー バージョンの後でも、簡単にコンパイルできるように調整できるのは不思議です!


PdfReader現在の iText バージョンでは、メソッドgetPageN(final int pageNum)またはを使用して特定のページの辞書を取得できますgetPageNRelease(final int pageNum)

ただし、現在のPdfReaderメソッドgetPageResources(final int pageNum)が特定のページのリソースを返すとは思わないでください。ただし、(サンプル コードと同様に) ResourcesディクショナリのPageディクショナリのみを参照するためです。


iText 5.0.1を使用する特定の理由はありますか? そのバージョンはかなり古く、それ以降、多くのバグ修正と機能が適用されています。

于 2015-07-08T21:37:54.620 に答える