PDFが1ページかどうかファイルの内容から判断する
問題
PDFが1ページかどうかを、なるべく簡単に判定したい。
どうするとよい?
答え
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
コメント