2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Pythonのスクリプトで見開きのPDFを半分に切る

Posted at

背景

最近知ったのですが,中学受験にはA3対応のプリンタ/スキャナは必須だと言われているらしいです.確かにプリンタ,スキャナの使用頻度は高く,特にスキャンは面倒なのでA3/B4でできるといいなと思い,Amazonで人気のBrother MFC-6583CDWを購入しました.(品薄で,ポチってから届くまで約一ヶ月かかりました.)

今までA4とかB5の単位でスキャンしていたのが,A3とかB4の見開きでスキャンできて一見楽になったように思えましたが,印刷などを考えると見開きで1ページなのはあまり嬉しくないのでできれば見開きのページを半分に切って保存したいと思いました.

そこで,やりかたをいろいろ調べてみたのですが,意外と面倒くさそうということが分かりました.普段使っているMacだけでなくWindowsも含めてやり方のバリエーションとして調べてみたところ以下の通りいくつか見つかりましたが決め手に欠く状況でした.

  • Adobe Acrobat DCを使う(mac,win) →有料
  • Adobe Acrobat Reader DC + VipRiser(mac) →ファイルサイズが大きくなるらしい
  • Adobe Acrobat Reader DC(win) →Adobe PDFとポスター印刷で可能だが,順番が期待通りにならないのと回転して保存ができない?

もう少し調べると,Pythonのライブラリである"PyPDF2"を使うとPDFファイルの操作ができそうということなので,ちょっと作ってみることにしました.

やりたいこと

  • 普通にスキャンすると左のようになるのを,右のようにしたい
    • 国語のように縦書きのものも,オプションできちんとした順番になるようにしたい

tobe.png

環境

  • macOS: 12.4
  • python: 3.9.9
  • PyPDF2: 2.3.1

実装と使い方

まず,PDFを半分に切ったりするには座標系の知識が必要かと思い少し調べたところ,PDFでは左上ではなく左下が(0,0)らしいということがわかりました.図の中のx0とかy1とかはスクリプトの中に出てくる変数です.
coordinate.png

以下のスクリプトを適当な名前(facing_page_cutter.pyなど)をつけて保存して,

  • python3 facing_page_cutter.py <filename>.pdf
    もしくは実行権限(chmod u+x facing_page_cutter.py)をつけて
  • /path/to/facing_page_cutter.py <filename>.pdf
    とすると,実行したディレクトリに<filename>_cut.pdfというファイルが作成されます.
    縦書きの時には-vをオプションとしてファイル名の前につけてください.

スクリプトの内容については見ていただければわかるかと思います.

facing_page_cutter.py
#!/usr/bin/env python3
# Copyright (c) 2022, Kazuhiro FUJIHARA

import PyPDF2
from optparse import OptionParser
import sys
import re
import copy

ROTATE_ANGLE = 90

# オプションや引数の処理
usage = "usage: /path/to/%prog [options] <pdf filename w/ .pdf>"
parser = OptionParser(usage = usage)
parser.add_option("-v", "--vertical", action="store_true", dest="vertical", help="縦書き")

(options, args) = parser.parse_args()

if len(args) != 1:
    parser.print_help()
    sys.exit()

output_filename = re.match(r'(.*)\.pdf', args[0]).groups()[0] + '_cut.pdf'

# ファイルを開く
pdf_reader = PyPDF2.PdfFileReader(args[0])
pdf_writer = PyPDF2.PdfFileWriter()

# ページの大きさを取得する
page = pdf_reader.getPage(0)
(x0, y0) = page.mediaBox.getLowerLeft()
(x1, y1) = page.mediaBox.getUpperRight()

# 見開き1ページずつ処理をしていく
for i in range(pdf_reader.getNumPages()):
    # 半分のサイズを抽出する(p1が左,p2が右のページ)
    p1 = pdf_reader.getPage(i)
    p2 = copy.copy(p1)
    p1.cropBox.lowerLeft = (x0, y0)
    p1.cropBox.upperRight = (x1, (y0 + y1) / 2)
    p2.cropBox.lowerLeft = (x0, (y0 + y1) / 2)
    p2.cropBox.upperRight = (x1, y1)
    
    # 縦書きの時は右のページが先に来るようにする
    if options.vertical is True:
        p1, p2 = p2, p1
    
    # 時計回りに90度回転させる
    p1.rotateClockwise(ROTATE_ANGLE)
    p2.rotateClockwise(ROTATE_ANGLE)

    # PDFの再構成
    pdf_writer.addPage(p1)
    pdf_writer.addPage(p2)

# ファイルへの書き出し
with open(output_filename, mode='wb') as f:
    pdf_writer.write(f)

最後に

色々試行錯誤しているときには

  • macで回転
  • winで分割
  • macで並べ替え

とやったりしてたのですが,とりあえずこのscriptで今のところ随分楽になりました.
やっぱり楽をするための努力は惜しまないように,と思った次第です...

2
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?