はじめに
フォルダごとに分けた大量の画像があるのですが、簡単に取り扱えるようにフォルダごとのPDFファイルに変換しようと思いました。
最初は、Adobeを使ったり、cubePDFを使ったりしたのですが、どちらも実行速度が遅いという問題がありました。そのため、Pythonでプログラムを作ることにしました。
プログラムを調べたところ、以下のプログラムが見つかりました。
高速で、ロスレスでPDFに変換できるimg2pdf
というライブラリを使用してます。
基本的にはこれをベースに、少し使いにくかった部分を変更しました。
できること
こんなフォルダがあったときに、
画像まとめ
├── 2015
│ ├── img1.jpg
│ ├── img2.jpg
│ ├── img3.jpg
├── 2016
│ ├── img10.jpg
│ ├── img11.jpg
│ ├── img12.jpg
├── 2017
│ ├── img21.jpg
│ ├── img22.jpg
│ ├── img23.jpg
画像まとめ
という親フォルダをドラッグアンドドロップすることで、以下のように子フォルダ名を使用したPDFファイルに変換することができます。
画像まとめ
├── 2015
│ ├── img1.jpg
│ ├── img2.jpg
│ ├── img3.jpg
├── 2016
│ ├── img10.jpg
│ ├── img11.jpg
│ ├── img12.jpg
├── 2017
│ ├── img21.jpg
│ ├── img22.jpg
│ ├── img23.jpg
├── 2015.pdf
├── 2016.pdf
├── 2017.pdf
ライブラリのインポート
pip install img2pdf
コード
import img2pdf
from pathlib import Path
import re
# 数字がない文字列は前に持ってきている。
# 逆にしたいときは代2引数にfloat('inf')を指定
# https://note.nkmk.me/python-sort-num-str/
def extract_num(s, ret=0):
p = re.compile(r'(\d+)')
search = p.search(s)
if search:
return int(search.groups()[-1])
print(search.groups())
else:
return ret
# 単処理
def ImageToPdf(outputpath, imagepath):
'''
outputpath: pathlib.Path()
imagepath: pathlib.Path()
'''
lists = list(imagepath.glob("**/*"))#単フォルダ内を検索
#jpg,pngファイルだけpdfに結合
#Pathlib.WindowsPath()をstring型に変換しないとエラー
#jpegにも対応
imgpath_list = [str(i) for i in lists if i.match("*.jpg") or i.match("*.png") or i.match("*.jpeg")]
#https://note.nkmk.me/python-sort-num-str/
#0埋めされていない番号順に対応
imgpath_list.sort(key=lambda s: extract_num(s))
#pdfを作成
with open(outputpath,"wb") as f:
f.write(img2pdf.convert(imgpath_list))
print(outputpath.name + " :Done")
# 複数フォルダをループ処理する
while True:
#作業フォルダ
base_path = input("PDFに変換したいファルダが入った親フォルダをd&Pしてください")
base_path = base_path.strip(" \' ")
#作業フォルダ内のディレクトリだけを抽出する
glob = Path(base_path).glob("*")
imagefolderlist = list([item for item in list(glob) if item.is_dir()])
#outputpathに指定ディレクトリと同名を指定する
outputpathlist = list([item.with_name(item.name + ".pdf") for item in imagefolderlist])
#ループ処理を行う
for outputpath,imagepath in zip(outputpathlist,imagefolderlist):
try:
ImageToPdf(outputpath,imagepath)
except:
import traceback
traceback.print_exc()
変更点
こちらのプログラムとの変更点は、
・パスをプログラム内に書かなければいけなかったところを、フォルダをドラックアンドドロップしてどんどん変換できるようにしました。
・.jpeg
の拡張子に対応していなかったので対応させました。
・エラー内容を表示させるようにしました。
・0埋めされていないファイルも番号順に並べるようにしました。例えば、{1, 2, 10}を並べ替えると、{1,10,2}となってしまい、本来回避するためには、{01, 02, 10}と0で埋めないといけないです。なお、番号がないファイルは前に持ってこられます。
ライブラリのアップデートによって改善されたこと
以前はアルファチャンネルを含むPNG画像は変換できずにエラーになっていました。
しかし2021/8/22のアップデートで、ソフトマスクを使用してアルファチャンネルのデータを保ったままPDFに変換できるようになりました。
まとめ
フォルダで分けられた画像を、pdfに一気に変換するときに便利です。
ぜひ使ってください。