何がしたいのか
会議等資料で、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
参考
- ページ分割は
https://unix.stackexchange.com/questions/12482/split-pages-in-pdf/12483#12483
を使って、ここから並び替えと回転をやっているイメージです。