SOFTELメモ Developer's blog

会社概要 ブログ 調査依頼 社員募集 ...

PDFが1ページかどうかファイルの内容から判断する

問題

PDFが1ページかどうかを、なるべく簡単に判定したい。

どうするとよい?

pdf

答え

PDFファイルをテキストエディタで開いてみると、文字化けしつつも、ある程度内部の構造を見ることができる。

このあたりが「ページ一覧オブジェクト」。

2 0 obj
<<
/Type /Pages
/Kids 
[
5 0 R
23 0 R
]
/Count 2
/ProcSet [/PDF /Text /ImageB /ImageC]
>>
endobj

2ページだと上のようになっているし、1ページだと下のようになっている。

2 0 obj
<<
/Type /Pages
/Kids 
[
5 0 R
]
/Count 1
/ProcSet [/PDF /Text /ImageB /ImageC]
>>
endobj

/Kids に続くページ一覧を数えるのが一番正確そうだが、/Count に続く数字を見させてもらって楽をするのもよいか。


phpの正規表現で1ページかどうか調べるとこんな感じでしょうか。

/**
 * こんな感じの部分が存在すれば1ページだと判断する
 * <<
 * /Type /Pages
 * 何か
 * /Count 1
 * 何か
 * >>
 */
$pdf = file_get_contents('test.pdf');
if (preg_match('|\n<<\n/Type /Pages\n[^<]*/Count 1\n[^<]*\n>>\n|s', $pdf)) {
	echo '1ページです';
} else {
	echo '1ページではないです';
}

改行の入り方や空白の入り方、要素の登場する順番などは、PDFの作り方によって若干異なるかもしれないので、雰囲気としては大体こんな感じで、後は状況に応じて調整する。

下のようになっていたり、<< >>が入れ子になっていたりするので、どこまで考慮するか。

2 0 obj
  << /Type /Pages
    /Kids [ 4 0 R
      10 0 R
      24 0 R
      ]
    /Count 3
  >>
endobj

サーバー側で特定のソフトウェアを使用して生成しているPDFをチェックする場合などなら、対応するべきパターンは限定できると思う。


他の方法としては、ページオブジェクトの個数を数える案も考えられる。以下のような「/Type /Page」の数を数える。

5 0 obj
<<
/Type /Page
/Parent 2 0 R
/Contents 19 0 R
/Resources 21 0 R
/Annots 22 0 R
/MediaBox [0 0 420 283]
>>
endobj

参考

http://www.kobu.com/docs/pdf/pdfxhand.htm

関連するメモ

コメント