インフラ系SEの技術メモ

雑なエンジニアが低信頼性のメモを書いています。参考程度にとどめてください。

(Python)Linuxで見開きのPDFページを2ページに分割する

はじめに

横長の1枚PDFを2枚の縦長に分割する方法を探していた際に発見した以下のページ。

確かにコピペで動いたので、Linux環境(Debian)でも動いたよ、というのを残しておきます。ちなみに同機能をAdobeやオンラインサービスで対応するのはかなり骨が折れるのでこれで実施できるのは画期的だと感じました。

動作環境&動作方法

# python3 --version
Python 3.5.3
# python3 -m pip install PyPDF2
DEPRECATION: Python 3.5 reached the end of its life on September 13th, 2020. Please upgrade your Python as Python 3.5 is no longer maintained. pip 21.0 will drop support for Python 3.5 in January 2021. pip 21.0 will remove support for this functionality.
Collecting PyPDF2
  Downloading PyPDF2-1.26.0.tar.gz (77 kB)
     |████▎                           | 10 kB 6.1 MB/s eta 0:0     |████████▌                       | 20 kB 3.3 MB/s eta 0:0     |████████████▊                   | 30 kB 2.5 MB/s eta 0:0     |█████████████████               | 40 kB 2.8 MB/s eta 0:0     |█████████████████████▏          | 51 kB 2.9 MB/s eta 0:0     |█████████████████████████▍      | 61 kB 3.2 MB/s eta 0:0     |█████████████████████████████▋  | 71 kB 3.4 MB/s eta 0:0     |████████████████████████████████| 77 kB 204 kB/s
Building wheels for collected packages: PyPDF2
  Building wheel for PyPDF2 (setup.py) ... done
  Created wheel for PyPDF2: filename=PyPDF2-1.26.0-py3-none-any.whl size=61175 sha256=XX
  Stored in directory: /root/.cache/pip/wheels/41/2c/b1/XX
Successfully built PyPDF2
Installing collected packages: PyPDF2
Successfully installed PyPDF2-1.26.0

スクリプト準備。

import PyPDF2
import copy

input_file = "./input.pdf"
output_file = "./output.pdf"
pdf_reader = PyPDF2.PdfFileReader(input_file)
pdf_writer = PyPDF2.PdfFileWriter()
for i in range(pdf_reader.getNumPages()):
    p1 = pdf_reader.getPage(i)
    p2 = copy.copy(p1)
    x0 = p1.mediaBox.getLowerLeft_x()
    y0 = p1.mediaBox.getLowerLeft_y()
    x1 = p1.mediaBox.getUpperRight_x()
    y1 = p1.mediaBox.getUpperRight_y()
    p1_lower_left = (x0, y0)
    p1_upper_right = ((x0 + x1) / 2, y1)
    p2_lower_left = ((x0 + x1) / 2, y0)
    p2_upper_right = (x1, y1)
    if abs(y1 - y0) > abs(x1 - x0):
        p1_upper_right = (x1, (y0 + y1) / 2)
        p2_lower_left = (x0, (y0 + y1) / 2)
    p1.cropBox.lowerLeft = p1_lower_left
    p1.cropBox.upperRight = p1_upper_right
    p2.cropBox.lowerLeft = p2_lower_left
    p2.cropBox.upperRight = p2_upper_right
    if abs(y1 - y0) > abs(x1 - x0):
        p1, p2 = p2, p1
    pdf_writer.addPage(p1)
    pdf_writer.addPage(p2)
with open(output_file, mode="wb") as f:
    pdf_writer.write(f)

実行&ファイル確認。

# python3 test.py
# ls -ltr
-rwx------ 1 root root  1159242 10月 12 11:34 input.pdf
-rw-r--r-- 1 root     root      1143588 10月 12 11:35 output.pdf

PDFを開くと、確かに想定通り分割されていました。冒頭に添付したサイト様及び同ライブラリを開発したチームの方には感謝感謝です。