PDFを扱う開発のお供にQPDFのすすめ

QPDFは、PDFの加工や調査に使えるライブラリおよびコマンドラインツールです。
主にPDFを扱った開発やPDFファイルの構造について学習する人をターゲットにしたソフトウェアとなっています。

PDFを表示したりコンテンツを編集したりといった高レベルなインターフェイスがない代わりに、PDFファイルの内部構造を調査したり操作するための低レベルなインターフェイスを備えています。
他のツールではなかなかできないような、データ構造を直接編集する機能も備えているため、PDFファイルを扱うソフトウェアの開発に大いに役立ちます。

macOSであればHomebrew、WindowsであればScoopでインストールできます。

[QPDF: A Content\-Preserving PDF Transformation System](https://qpdf.sourceforge.io/)

## QPDFの主な機能

- 基本的な操作
  - 暗号化／暗号化の解除
  - ページの回転
  - 分割
  - 結合
  - リニアライズ（Web用最適化）
  - 添付ファイルの追加／削除
- PDFの検査
  - PDFファイルの妥当性検査
  - 暗号化の有無や暗号化パラメータの確認
  - クロスリファレンスの表示
  - ページ数の表示
  - ページオブジェクトの情報表示
  - オブジェクトの情報表示
  - 添付ファイルの情報表示
  - PDFのデータ構造をJSON形式で出力
- QDFモード
  - テキスト編集可能な形式に変換して、直接編集できるようにするモード

このような感じで、一般ユーザーというよりはデベロッパー向けに嬉しい機能が備わっています。

## 使用例

- [暗号化](#暗号化)
- [ページの回転](#ページの回転)
- [分割](#分割)
- [結合](#結合)
- [リニアライズ（Web用最適化）](#リニアライズ)
- [PDF構造のダンプ](#pdf構造のダンプ)
- [QDFモード](#qdfモード)

### 暗号化

いわゆるパスワード付きPDFというやつです。

```bash
# 暗号化
# PDFは機能ごとにパスワードで制御をかけられるようになっていて
# KEY-LENGTH(40|128|256)によって制御できる範囲が異なる
qpdf --encrypt <USER-PASSWORD> <OWNER-PASSWORD> <KEY-LENGTH> --print=y --modify=y --extract=y --annotate=y -- input.pdf output.pdf

# 暗号化を解除する
qpdf --decrypt --password=<PASSWORD> input.pdf output.pdf
```

PDFは印刷だとかテキストコピーだとか機能ごとに許可設定が行えるようになっていて、それらもパラメーターで設定できるようになっています。

また、閲覧時に必要なユーザーパスワードと権限の設定時に必要なオーナーパスワード（または権限パスワード）があります。

### ページの回転

ページの回転は90度単位で指定できます。
実質的に指定できる値は`0`, `90`, `180`, `270`です。

特定のページのみ回転することもできます。

```bash
# 回転
qpdf --rotate=90 input.pdf output.pdf

# 現在の回転状態から更に回転
# +/-指定で現在の回転状態からの相対的な回転が行える
qpdf --rotate=+90 input.pdf output.pdf

# 1ページ目と3-5ページ目を回転
qpdf --rotate=90:1,3-5 input.pdf output.pdf
```

### 分割

ページごとに分割したPDFファイルを生成できます。

```bash
# 1ページ単位でPDFを分割
# output-01.pdfのようなファイルが生成される
qpdf --split-pages input.pdf output.pdf

# Nページ単位でPDFを分割
qpdf --split-pages=<N> input.pdf output.pdf
```

### 結合

複数のPDFを結合できます。

結合したいPDFファイルの他に、文書のプロパティなどベースとなるメタデータを持つPDFファイルを指定するか、`--empty`を指定する必要があります。

```bash
# A.pdfの1-3ページのあとにB.pdfの5-7ページを結合したPDFを生成する
#
# base.pdfに文書のプロパティなどベースとなるPDFファイルを指定する
# 空のプロパティで作りたい場合は--emptyを指定できる
qpdf base.pdf --pages A.pdf 1-3 B.pdf 5-7 -- output.pdf

# A.pdfの1ページ目
# B.pdfの1ページ目
# A.pdfの2ページ目
# B.pdfの2ページ目
# ……のように交互に結語する
qpdf base.pdf --collate --pages A.pdf B.pdf -- output.pdf

# nページごとにもできる
qpdf base.pdf --collate=2 --pages A.pdf B.pdf -- output.pdf
```

### リニアライズ

Linearized PDFを生成します。

通常のPDFファイルはファイルの最後まで読み込まないと表示することができませんが、Linearized PDFにすると読み込みながら表示を開始することができます。
大きいPDFファイルをWebに掲載する場合などに利用されます。

```bash
# リニアライズ（Web用最適化）
qpdf --linearize input.pdf output.pdf
```

### PDF構造のダンプ

PDFの構造をJSON形式でダンプすることができます。

PDFの内部構造の知識がないと何が何やらですが、解析や調査の際に重宝します。

```bash
# PDFのオブジェクト構造をJSONで出力
qpdf --json input.pdf
```

## QDFモード

通常、PDFファイルはコンテンツが圧縮されていたり画像などのバイナリデータが含まれているため、テキストエディタで編集することはできませんが、QDFモードというのを利用することでテキスト編集可能な形式に変換することができます。

変換して編集したファイルは`fix-qdf`というQPDFに同梱されているコマンドでPDFファイルに書き戻すことができます。

このモードを利用することで、PDFの内部構造を調査したり、オブジェクトのパラメータ等を直接書き換えるような編集が可能になります。
PDFに関する深い知識が必要になりますが、PDFの内部データを自由に編集できるため、データ構造に深く関わるような開発をする際に大変役に立ちます。

```bash
# QDFファイルに変換する
qpdf --qdf input.pdf output.qdf

# テキストエディタで編集する
$EDITOR output.qdf

# QDFファイルからPDFファイルに戻す
fix-qdf <output.qdf >new.pdf
```

## まとめ

QPDFには非常に沢山の機能があるため、よく使いそうな機能に絞って紹介してみましたが、これだけでもPDFファイルを扱うソフトウェア開発に大いに役立つであろうことがお分かりいただけたかと思います。
特にQDFモードは大変強力なため、是非とも一度体験してみてください。

## 参考

- [QPDF version 10\.6\.3 — QPDF 10\.6\.3 documentation](https://qpdf.readthedocs.io/en/stable/)
- [QPDF \- TeX Wiki](https://texwiki.texjp.org/?QPDF)
- [Qpdf : コマンドラインのPDFツール \| PDF](http://pdf-file.nnn2.com/?p=865)