簡単便利!PHPでPDFをテキスト&画像ファイルに変換する方法

さてさて、近年はウェブ開発の世界も成熟してきて、その昔は実行するには手間暇がかかり過ぎることでもいまだと簡単に実行できるようになってきました。

もちろん、PHPだけでは実行が難しい作業もたくさんありますが、サーバー内の他のプログラムと連携することで何の問題もなく開発できるため、ウェブだけでもデスクトップのような動きを実現することができたりします。

そこで、今回はそんな中からPDFをテキスト&画像ファイルに変換する方法をお届けしたいと思います。

ぜひ学習に役立ててくださいね。

※ 開発環境:Laravel 5.7 + Ubuntu 18.04 (通常のPHPでも実行できます)

用意するもの

テキストが含まれたPDF。
もし手持ちがない場合は以下にサンプルを用意しましたので、そちらからダウンロードしてください。(中身は、夏目漱石の『吾輩は猫である』冒頭部分です)

吾輩は猫である:冒頭部分(PDF)

 

ダウンロードしたら、storage/app/pdfファルダをつくり、そこへ移動させておいてください。

※ ちなみに、ファイルを移動させただけではPHP側から呼び出せない可能性があります。その場合はsudo chmod -R 777 storageなどで実行権限を与えておいてください。

PDFをテキストファイルに変換する

変換の流れ

PDFをテキストファイルに変換するには以下の流れになります。

  1. PDFからテキスト文章を抜き出す
  2. 抜き出したテキストをファイルに保存する

では実際にやってみましょう。

pdftotextをインストールする

今回の方法は、直接PHPでPDFを扱うのではなく、pdftotextというオープンソースをPHP側から呼び出して実行します。そのため、まずはpdftotextをインストールしておきましょう。

まず、すでにインストールされているかをチェックします。

pdftotext -v

もしインストールされていたら、以下のようにバージョン情報が表示されることになります。

pdftotext version 0.62.0
Copyright 2005-2017 The Poppler Developers - http://poppler.freedesktop.org
Copyright 1996-2011 Glyph & Cog, LLC

インストールされていない場合は次のコマンドで実行しましょう。

Ubuntu or Debian

sudo apt install poppler-utils

Redhat or CentOS

sudo yum install poppler-utils

パッケージをインストールする

PHPにはpdftotextを簡単に利用できるパッケージが公開されているのでこれを利用します。インストールはcomposerで一発です。

composer require spatie/pdf-to-text

PDFをテキストに変換する

では、まずはPDFからテキスト文章を抜き出す部分です。

$pdf_path = storage_path('app/pdf/wagahaihanekodearu.pdf');
$text = \Spatie\PdfToText\Pdf::getText($pdf_path);

$text<pre></pre>タグで囲んで表示したものがこちらです。

なお、第2引数はコマンドラインのpdftotextがある場所を指定することができます。もしうまくいかない場合は以下のコマンドを実行し、表示されたパスをこの引数に指定してみるといいでしょう。

which pdftotext
Pdf::getText($pdf_path, '/usr/bin/pdftotext');

また、第3引数ではpdftotextのオプション情報を指定することができます。
今回の例で関連するオプションは以下のようになります。

  • f ・・・ 開始ページを指定
  • l ・・・ 終了ページを指定
  • r ・・・ 解像度(DPI)。デフォルトは 72 DPI
  • x ・・・ 切り抜きエリアのX座標
  • y ・・・ 切り抜きエリアのY座標
  • W ・・・ 切り抜きエリアの横幅
  • H ・・・ 切り抜きエリアの高さ
  • layout ・・・ できるだけ元のレイアウトでテキストを抽出する
  • htmlmeta ・・・ HTMLとして出力。つまりHTMLタグが入る
  • enc ・・・ 出力する文字コード。「Shift-JIS」「EUC-JP」など。 *1
  • eol ・・・ 改行コードを指定。「unix」「dos」「mac」
  • nopgbrk ・・・ 改ページを含まない。
  • opw ・・・ 所有者のパスワード
  • upw ・・・ ユーザーのパスワード

*1 pdftotext -listencとコマンド入力すると利用できる文字コードの一覧を確認することができます。

では、せっかくなので上のオプションxyWHを使って範囲を指定し、ヘッダーやフッター情報を除去したテキストを取得してみましょう。

(イメージ)

コードはこうなります。

$text = Pdf::getText($pdf_path, '/usr/bin/pdftotext', [
    'x 0',    // X座標
    'y 30',   // Y座標
    'W 1000', // 横幅
    'H 500'   // 高さ
]);

実行結果です。

あとは、file_put_content()を使ってテキストファイルを作成すれば変換は完了です。

$text_path = storage_path('app/text/wagahaihanekodearu.txt');
file_put_contents($text_path, $text);

PDFを画像に変換する

ImageMagickとGhostScriptをインストールする

PDFを画像に変換するにはImageMagickGhostScriptを利用します。

もし、以下のコマンドでチェックして見つからない場合はインストールしておきましょう。

  • gs -v ・・・ GhostScriptのバージョンチェック
  • convert -v ・・・ ImageMagickのバージョンチェック

UbuntuもしくはDebian

sudo apt install ghostscript
sudo apt install imagemagick

RedhatもしくはCentOS

sudo yum install ghostscript
sudo yum install ImageMagick

パッケージをインストールする

こちらのパッケージもcomposer一発で完了します。

composer require spatie/pdf-to-image

PDFを画像へ変換する

では、実際のコードです。

$pdf_path = storage_path('app/pdf/wagahaihanekodearu.pdf');
$pdf = new \Spatie\PdfToImage\Pdf($pdf_path);

$image_path = storage_path('app/images/wagahaihanekodearu.jpg');
$pdf->saveImage($image_path);

まずはPdfToImageにPDFのパスを入れてインスタンスをつくり、さらにsaveImage()で保存場所を指定するだけです。とてもシンプルですね。

実際に作成したJPEG画像です(ただし、縮小してます)

もし「not authorized」と表示されたら

もし以下のようなエラーが表示された場合はImageMagickがPDFを使える設定になっていません。

ImagickException (499)
not authorized `******.pdf' @ error/constitute.c/ReadImage/412

この場合は、ImageMagickがインストールされているフォルダ内のpolicy.xml(例:/etc/ImageMagick-6/policy.xml)を開いて以下の部分を変更しましょう。

<policy domain="coder" rights="none" pattern="PDF" />

↓↓↓ 変更する

<policy domain="coder" rights="read|write" pattern="PDF" />

そして、大事なのがウェブサーバーを再起動することです。nginx + php-fpmの場合は両方再起動しましょう。

sudo systemctl restart apache
sudo systemctl restart nginx
sudo systemctl restart php7.2-fpm

などなど。

様々なオプション

PdfToImageには色々なオプションが利用できるようになっています。
ひとつずつ見ていきましょう。

ページ番号を指定する

画像に変換したいページ番号を指定することができます。

$pdf->setPage(2); // PDFの2ページ目だけ変換

画像形式を指定する

保存する画像形式を指定することができます。

$pdf->setOutputFormat('png'); // pngで保存

※ ただし指定できるのは、jpgjpegpngの3種類だけで、デフォルトはjpgです。

画質を指定する

保存する画像の画質を指定することができます。

$pdf->setCompressionQuality(100);

解像度を指定する

画像の解像度を指定することができます。

$pdf->setResolution(144);

画像のレイヤーを合成する

$pdf->setLayerMethod(\imagick::LAYERMETHOD_COALESCE);

利用できるパラメータは、以下のとおりです。

  • imagick::LAYERMETHOD_UNDEFINED
  • imagick::LAYERMETHOD_COALESCE
  • imagick::LAYERMETHOD_COMPAREANY
  • imagick::LAYERMETHOD_COMPARECLEAR
  • imagick::LAYERMETHOD_COMPAREOVERLAY
  • imagick::LAYERMETHOD_DISPOSE
  • imagick::LAYERMETHOD_OPTIMIZE
  • imagick::LAYERMETHOD_OPTIMIZEPLUS
  • imagick::LAYERMETHOD_OPTIMIZEIMAGE
  • imagick::LAYERMETHOD_OPTIMIZETRANS
  • imagick::LAYERMETHOD_REMOVEDUPS
  • imagick::LAYERMETHOD_REMOVEZERO
  • imagick::LAYERMETHOD_COMPOSITE
  • imagick::LAYERMETHOD_MERGE
  • imagick::LAYERMETHOD_FLATTEN
  • imagick::LAYERMETHOD_MOSAIC (integer)

その他

PDFのページ数を取得する

セットしたPDFのページ数を取得することができます。

$pdf->getNumberOfPages(); // ページ数を取得

画像の形式をサポートしているかチェックする

if(!$pdf->isValidOutputFormat('gif')) {

    echo 'この形式はサポートしていません。';

}

ImageMagickのインスタンスを取得する

$imagick = $pdf->getImageData();

今回のソースコードをダウンロード

実際今回の開発で使ってプログラム・コードを以下からダウンロードすることができます。

※ ただし、ImageMagickなどのインストールは各自で行ってください。

PDFをテキスト&画像ファイルに変換: PHPプログラム・コード

 

この記事が役立ちましたらシェアお願いします😊✨