はじめに
最近,A3,B4をスキャンできるスキャナを購入したが,
両面同時スキャン対応していなかった (´;ω;`)
両面プリントの束をスキャンするときに,
面倒だが片面ずつスキャンしてPDFファイルをマージする必要がある
10枚の両面プリントをスキャンしたとき(A:表面,B:裏面,数字は枚目)
1回目のスキャンでできたPDF:1A,2A,3A,・・・,10A
2回目のスキャンでできたPDF:1B,2B,3B,・・・,10B
これを,
マージしたPDF:1A,1B,2A,2B,・・・,10A,10B
とする必要がある
プログラム設計
書くべきほどのことではないが,簡単に書くとこんな感じであろう
- 引数は,結合する2つのファイル名と出力するファイル名
- 結合する2つのファイルの存在チェック
- 結合する2つのページ数が同じかチェック
- 1ページごと交互に新しいファイルに書いていく
PyPDF2
python で PDF ファイルを扱うなら PyPDF2 がよさそうだ
インストールは,conda なら
conda install PyPDF2
PDFファイルのページ数を得る
PdfFileReader
の getNumPages
を使えばよい
PdfFileReader
の生成にはファイル名を渡す
PdfFileReader(stream, strict=True, warndest=None, overwriteWarnings=True)
## stream: Could also be a string representing a path to a PDF file.(抜粋)
getNumPages
はただ呼ぶだけでよい
getNumPages()
つまり,これだけでページ数が取得できる
import PyPDF2
reader = PyPDF2.PdfFileReader('src.pdf')
page_num = reader.getNumPages()
PDFファイルの1ページを得る
PdfFileReader
の getPage
を使えばよい
getPage(pageNumber)
pageNumber
は 0始まりだ
つまり,これだけで全ページが取得できる
import PyPDF2
reader = PyPDF2.PdfFileReader('src.pdf')
page_num = reader.getNumPages()
for page_number in range(page_num):
page = reader.getPage(page_number)
PDFファイルに出力する
PdfFileWriter
を生成し,addPage
でページを追加,write
で PDF へ書き込む
addPage
,write
は次のようで
addPage(page)
write(stream)
addPage
の page
には PdfFileReader.getPage
で取得した page
を渡す
write
の stream
はファイルオブジェクトを渡す
以下のソースで,src.pdf が dest.pdf にコピーされる
import PyPDF2
reader = PyPDF2.PdfFileReader('src.pdf')
page_num = reader.getNumPages()
writer = PyPDF2.PdfFileWriter()
for page_number in range(page_num):
page = reader.getPage(page_number)
writer.addPage(page)
with open('dest.pdf', 'wb') as f:
writer.write(f)
2つのPDFファイルを交互に結合する
import os
import argparse
import PyPDF2 as pp
# 引数の解析
parser = argparse.ArgumentParser()
parser.add_argument('file1', help='元ファイル1', type=str)
parser.add_argument('file2', help='元ファイル2', type=str)
parser.add_argument('--output', '-o', help='出力ファイル名', type=str, default='output.pdf')
arg = parser.parse_args()
# 引数
file1 = arg.file1
file2 = arg.file2
output = arg.output
# 引数のチェック
if not os.path.exists(file1):
print(f'{file1}が存在しません')
quit()
if not os.path.exists(file2):
print(f'{file2}が存在しません')
quit()
reader1 = pp.PdfFileReader(file1)
reader2 = pp.PdfFileReader(file2)
if reader1.getNumPages() != reader2.getNumPages():
print('ページ数が異なります')
quit()
# 1ページずつ交互に新しいファイルに書き込む
writer = pp.PdfFileWriter()
for page in range(reader1.getNumPages()):
writer.addPage(reader1.getPage(page))
writer.addPage(reader2.getPage(page))
with open(output, 'wb') as f:
writer.write(f)
おわりに
便利だな,PyPDF2
PDFファイルを扱うことが多いので,これから活用していきたい
追記
1回目のスキャンが完了した後,プリントの束をそのままひっくり返してスキャンする
通常このようにスキャンすると思うので,上のコードを修正をする
1回目のスキャンでできたPDF:1A,2A,3A,・・・,10A
2回目のスキャンでできたPDF:10B,9B,8B,・・・,1B
これをマージして,1A,1B,2A,2B,・・・,10A,10Bとしたい
2回目のスキャンファイルは逆順に読む必要がある
import os
import argparse
import PyPDF2 as pp
# 引数の解析
parser = argparse.ArgumentParser()
parser.add_argument('file1', help='元ファイル1', type=str)
parser.add_argument('file2', help='元ファイル2', type=str)
parser.add_argument('--output', '-o', help='出力ファイル名', type=str, default='output.pdf')
arg = parser.parse_args()
# 引数
file1 = arg.file1
file2 = arg.file2
output = arg.output
# 引数のチェック
if not os.path.exists(file1):
print(f'{file1}が存在しません')
quit()
if not os.path.exists(file2):
print(f'{file2}が存在しません')
quit()
reader1 = pp.PdfFileReader(file1)
reader2 = pp.PdfFileReader(file2)
if reader1.getNumPages() != reader2.getNumPages():
print('ページ数が異なります')
quit()
# 1ページずつ交互に新しいファイルに書き込む
writer = pp.PdfFileWriter()
num_pages = reader1.getNumPages()
for page_number in range(num_pages):
writer.addPage(reader1.getPage(page_number))
writer.addPage(reader2.getPage(num_pages-1-page_number)) ## 逆順に読む
with open(output, 'wb') as f:
writer.write(f)