手軽屋
ツール一覧

PDFのページ回転はなぜ90度単位だけなのか

PDF整理ツールやAdobe Acrobatでページを回転すると、必ず「90度・180度・270度」しか選べません。45度や30度の自由角度回転がない理由は、PDF仕様ISO 32000-1:2008の/Rotateエントリが整数倍90度だけを許可しているためです。本記事では仕様の根拠、フリー角度を実現する代替手段、setRotation関数の挙動を解説します。

※2026年6月時点のISO 32000-1:2008仕様とpdf-lib v1.17の実装を前提に解説しています。

1. ISO 32000-1:2008 /Rotate エントリの定義

PDF仕様(ISO 32000-1:2008、Adobeが寄稿しISO TC 171 SC 2 WG8が維持管理)では、各ページオブジェクト(Page dictionary)に「/Rotate」エントリを持たせることができます。

/Page <<
  /Type /Page
  /Rotate 90        % 表示時に時計回り90度回転
  /MediaBox [0 0 595 842]
  ...
>>

仕様書 7.7.3.3 Page Objects に明記されている通り、/Rotate の値は「90の整数倍(multiple of 90)」に限定されており、それ以外の値はビューアによって無視または0として扱われます。0が省略時のデフォルト。

2. なぜ90度単位なのか(設計上の理由)

PDFは1993年にAdobeが策定した時点で「PostScriptページ記述言語の上位互換として印刷向け」を志向しました。印刷業界では原稿を90度単位で台紙にレイアウトする慣習が深く、自由角度の指定はDTPソフト(QuarkXPress、Adobe InDesign)側で行うものとされてきました。

さらに自由角度回転を許すと、以下の問題が発生します。

3. pdf-lib の setRotation 関数挙動

pdf-lib(最新v1.17)のsetRotation関数は、内部的にdegrees(angle)ヘルパーで角度を受け取り、/Rotate エントリに書き込みます。

import { PDFDocument, degrees } from 'pdf-lib'

const pdfDoc = await PDFDocument.load(bytes)
const pages = pdfDoc.getPages()

// 90度回転
pages[0].setRotation(degrees(90))

// 既存の回転に追加
const current = pages[0].getRotation()
pages[0].setRotation(degrees(current.angle + 90))

pdf-libは45度を渡しても例外を投げません。ただし保存されたPDFを開くと、Adobe Acrobatや主要ビューアでは0度として表示されます。0/90/180/270 以外を渡すのは無意味です。

手軽屋のPDFページ整理ツールも、⟳ボタン1回で+90度、4回で0度に戻る循環設計にしています。

4. どうしても自由角度回転が必要なら

スキャン原稿が3度ほど傾いていて補正したい、という場面はあります。その場合は以下の手順を取ります。

  1. 1.PDF→JPG変換でページを画像化
  2. 2. 画像編集ソフト(GIMP、Photoshop、Affinity Photo)で自由角度回転
  3. 3. 余白を埋めて元と同じ用紙サイズに調整
  4. 4.画像→PDF変換でPDF化

ただしこの手順を踏むと、テキスト検索可能なテキストレイヤー(CIDフォント情報)は失われ、画像化されたページになります。検索性が必要なら、OCRをかけ直す必要があります。

5. 90度回転とフォント・画像の関係

/Rotateエントリだけを書き換える回転(pdf-libのsetRotationが行う処理)の利点は、ページ内コンテンツストリームを一切変更しない点です。

これがpdf-libのcopyPagessetRotation方式が高速・劣化なしで動く理由です。

まとめ

PDFのページ回転が90度単位なのはISO 32000-1:2008仕様の制約。pdf-libのsetRotationは /Rotateエントリだけを書き換えるためフォントも画像も劣化しません。自由角度が必要なら画像化→自由回転→PDF化の流れになりますが、テキスト検索性は失われます。手軽屋のPDFページ整理では仕様準拠の高速回転を提供しています。