LoginSignup
6
7

More than 3 years have passed since last update.

見開き中央綴じ資料をスキャンしたPDFをページ毎に分割する

Last updated at Posted at 2018-08-31

何がしたいのか

会議等資料で、A4見開き(紙自体はA3)で中央で綴じられている資料のホッチキスを外して、A3でスキャンして電子化(PDF化)してもそのままじゃページがばらばらで読めないのを何とかしたい。
真ん中で切断してスキャンしてもページがばらばらだし、PDF編集ソフトとかでページを並び替えたり回転したりするのも面倒。
そこでPyPDF2を使ってこの問題を解決してみました(これができるPDF編集ソフトが見つからなかったので…)。

やっていること

  • A3ページを縦に2分割する
  • ページを並び替えて読めるPDFにする
  • ページを回転させて正面から見れるようにする

前提

  • 想定しているのは、A4横の資料がA3に冊子形式で割り付けて印刷・中央綴じされているものです
  • スキャンするときは、見開いた状態で、最初のページがA3右側の一番下の裏になるようにして両面スキャンしたものを想定しています(この辺は並び替えとかをいじればどの方向でスキャンしてもできるはずです)
  • PDFファイルを標準入力から得て標準出力に書き出す

実装

準備

import copy, sys
from PyPDF2 import PdfFileWriter, PdfFileReader

input = PdfFileReader(open('/dev/stdin', 'rb'))
output = PdfFileWriter()

numPages = input.getNumPages()
spreadPages = [0] * (numPages*2)
sortedPages = [0] * (numPages*2)
  • PyPDF2を使います
  • PdfFileReaderで標準出力から読み込みます
  • spreadPagesには2分割ページを格納
  • sortedPagesには並び替えた結果を格納

A3ページを縦に2分割

j = 0
for p in [input.getPage(i) for i in range(0, numPages)]:
    q = copy.copy(p)
    (w, h) = p.mediaBox.upperRight
    p.mediaBox.upperRight = (w/2, h)
    q.mediaBox.upperLeft = (w/2, h)
    spreadPages[j*2] = p
    spreadPages[j*2 + 1] = q
    j = j + 1

ページを並び替え

    sortedPages[numPages - 1 - i*2] = spreadPages[i*4]
    sortedPages[numPages     + i*2] = spreadPages[i*4 + 1]
    sortedPages[numPages + 1 + i*2] = spreadPages[i*4 + 2]
    sortedPages[numPages - 2 - i*2] = spreadPages[i*4 + 3]

だいたい以下のイメージで、あとは1枚ずつ表と裏で4ページ分のページが本来どのページ番号になっていくかを考えてみた感じです。
* (4行目)iが最大のときに分割後の最後のページ(i*4 + 3)が最初のページ(numPages - 2 - i*2 = 0)になる
* (3行目)iが最大のときに分割後の最後から1つ前のページ(i*4 + 2)が最後のページ(numPages + 1 + i*2 = numPages*2 - 1)になる
* (1,2行目)i = 0のときに分割後の最初のページ(i*4 = 0)とその次のページが真ん中の2つのページになる

ページを回転

for i in range(0, numPages*2):
    output.addPage(sortedPages[i].rotateClockwise(90))
  • rotateClockwise(90)で時計回りに90°回転してます

出力

output.write(open('/dev/stdout', 'wb'))

全コード

#!/usr/bin/env python
import copy, sys
from PyPDF2 import PdfFileWriter, PdfFileReader

input = PdfFileReader(open('/dev/stdin', 'rb'))
output = PdfFileWriter()

numPages = input.getNumPages()
spreadPages = [0] * (numPages*2)
sortedPages = [0] * (numPages*2)

j = 0
for p in [input.getPage(i) for i in range(0, numPages)]:
    q = copy.copy(p)
    (w, h) = p.mediaBox.upperRight
    p.mediaBox.upperRight = (w/2, h)
    q.mediaBox.upperLeft = (w/2, h)
    spreadPages[j*2] = p
    spreadPages[j*2 + 1] = q
    j = j + 1

for i in range(0, numPages//2):
    sortedPages[numPages - 1 - i*2] = spreadPages[i*4]
    sortedPages[numPages     + i*2] = spreadPages[i*4 + 1]
    sortedPages[numPages + 1 + i*2] = spreadPages[i*4 + 2]
    sortedPages[numPages - 2 - i*2] = spreadPages[i*4 + 3]

for i in range(0, numPages*2):
    output.addPage(sortedPages[i].rotateClockwise(90))

output.write(open('/dev/stdout', 'wb'))

使いかた

$ python un2up.py < input.pdf > output.pdf

参考

6
7
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
6
7