megutech

自身の備忘録として主にWEBサーバー周りの技術について投稿しています。

FPDIでPDF1.5以降の圧縮されたファイルを何とかしたい

FPDIで色々していたら This PDF document probably uses a compression technique which is not supported by the free parser shipped with FPDI.というエラーが。

どうやらPDF1.5以降の圧縮されたPDFの回答は無償版のFPDIではできないとのこと。
んじゃライセンス買おうかと思ったけど、当然高い。

ということで無償で何とかする方法が以下。

環境

Service Version
CentOS 7.3
PHP 7.2.2

対応

QPDFインストール

必要なパッケージをインストール

$ yum install libjpeg-turbo libjpeg-turbo-devel

どうやらCentoOS7.3のgcc4.8では9.1.1のビルドが通らないらしいので、9.1.0を使用。

$ cd /usr/local/src
$ wget https://github.com/qpdf/qpdf/releases/download/release-qpdf-9.1.0/qpdf-9.1.1.tar.gz
$ tar xvfz qpdf-9.1.0.tar.gz
$ cd ./qpdf-9.1.0
$ ./configure --prefix=/usr/local/qpdf/v9.1.0
$ make
$ make install

パスを通す

$ cd /usr/local/qpdf/
$ ln -s ./v9.1.0 ./current
$ cd ./current/bin
$ ln -s /usr/local/qpdf/current/bin/qpdf 

PHPから使ってみる

以下適当なサンプル。

<?php

use setasign\Fpdi\TcpdfFpdi;
use Symfony\Component\Process\Exception\ProcessFailedException;
use Symfony\Component\Process\Process;

/**
 * 圧縮の解除
 *
 * @param string $inputPath
 * @param string $outputPath
 * @return string 圧縮解除したファイルのパス
 */
function uncompress(string $inputPath, string $outputPath): string
{
    if (! setlocale(LC_CTYPE, "UTF8", "ja_JP.UTF-8")) {
        throw \Exception('skip setlocale() failed');
    }

    $outputPath = escapeshellcmd($outputPath);
    $inputPath = escapeshellcmd($inputPath);
    $command = "qpdf --stream-data=uncompress --force-version=1.4 {$inputPath} {$outputPath}";

    $process = Process::fromShellCommandline($command);
    $process->run();

    if (! $process->isSuccessful()) {
        throw new ProcessFailedException($process);
    }

    return $outputPath;
}


$pdf = new TcpdfFpdi();
$pdf->setSourceFile(self::uncompress('/your/inputPath', '/your/outputPath'));

こんな感じで良い感じに書いてください。

雑感

Ghostscriptとかでやる方法などもあるみたいだけど、とりあえずこれで動いてるから一旦終わり!

あとPHPのサンプルは適当なので悪しからず。実際はこんな感じのコードをLaravelで書いて確認しました。