質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

2894閲覧

サブフォルダも含めた複数のフォルダ内の画像を、フォルダ毎に1つのPDFに変換したい

TomF

総合スコア4

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2021/01/15 02:52

下記の様にフォルダ階層毎にJPEGファイルがあるとして、それらJPEGをPDFに変換し、1つのファイルに結合したいです。
結合後のファイル名は、そのファイルが格納されているフォルダ名にしたいです。(成果物はどこにできても構いません)


【実行前】
root/
├─ A/
│ ├─ D/
│ | ├─ 005.jpg
│ | └─ 006.jpg
│ └─ E/
│ ├─ 007.jpg
│ └─ 008.jpg
├─ B/
│ └─ F/
│ ├─ 009.jpg
│ └─ 010.jpg
├─ C/
│ ├─ 003.jpg
│ └─ 004.jpg
├─ 001.jpg
└─ 002.jpg


【実行後】
root/
├─ A/
│ ├─ D/
│ | └─ D.pdf
│ └─ E/
│ └─ E.pdf
├─ B/
│ └─ F/
│ └─ F.pdf
├─ C/
│ └─ C.pdf
└─ root.pdf


Python

1import os 2import glob 3import img2pdf 4 5os.chdir(r'C:\root\A') 6cur_dir = os.getcwd() 7dirs = os.listdir(cur_dir) 8 9for f in dirs: 10 if os.path.isdir(os.path.join(cur_dir, f)): 11 files = glob.glob(os.path.join(cur_dir, f, r"*.jpg")) 12 with open(os.path.join(cur_dir, f, f"{f}.pdf"), "wb") as f1: 13 f1.write(img2pdf.convert([file for file in files]))

上記の様にos.chdir()に「A/」を指定すれば「D」と「E」のフォルダ直下に結合されたPDFを作ることができたので、「階層を上げて更にfor文の中でfor文を回せばできるだろう」と思ってやってもうまくいかず。
以下のコードだとエラーを吐かれてしまいます。

Python

1cur_dir = os.getcwd(r'C:\root') 2dirs = os.listdir(cur_dir) 3 4for f in dirs: 5 if os.path.isdir(os.path.join(cur_dir, f)): 6 for sf in os.listdir(os.path.join(cur_dir,f)): 7 if os.path.isdir(os.path.join(cur_dir, f, sf)): 8 files = glob.glob(os.path.join(cur_dir, f, sf, r"*.jpg")) 9 with open(os.path.join(cur_dir, f, sf, f"{sf}.pdf"), "wb") as f1: 10 f1.write(img2pdf.convert([file for file in files])) 11 12 files = glob.glob(os.path.join(cur_dir, f, r"*.jpg")) 13 with open(os.path.join(cur_dir, f, f"{f}.pdf"), "wb") as f1: 14 f1.write(img2pdf.convert([file for file in files]))

###Error
IndexError Traceback (most recent call last)
<ipython-input-25-b6702d2f1074> in <module>
18 files = glob.glob(os.path.join(cur_dir, f, r"*.jpg"))
19 with open(os.path.join(cur_dir, f, f"{f}.pdf"), "wb") as f1:
---> 20 f1.write(img2pdf.convert([file for file in files]))

C:\ProgramData\Anaconda3\lib\site-packages\img2pdf.py in convert(*images, **kwargs)
2082 return
2083
-> 2084 return pdf.tostring()
2085
2086

C:\ProgramData\Anaconda3\lib\site-packages\img2pdf.py in tostring(self)
953 def tostring(self):
954 stream = BytesIO()
--> 955 self.tostream(stream)
956 return stream.getvalue()
957

C:\ProgramData\Anaconda3\lib\site-packages\img2pdf.py in tostream(self, outputstream)
1047 # by default the initial page is the first one
1048 if self.engine == Engine.pikepdf:
-> 1049 initial_page = self.writer.pages[0]
1050 else:
1051 initial_page = self.writer.pagearray[0]

IndexError: Accessing nonexistent PDF page number


さらに「os.walk」を使えばできるかなと思い色々やってみましたが、os.walk()に指定したフォルダ直下のファイルしかPDFにできず。

Python

1for foldername, subfolders, filenames in os.walk(r'C:\root'): 2 files = glob.glob(os.path.join(cur_dir, foldername, r"*.jpg")) 3 with open(os.path.join(cur_dir, foldername, f"{foldername}.pdf"), "wb") as f1: 4 f1.write(img2pdf.convert([file for file in files]))

他にもabspathを使ったり、一度リストにJPEGを格納してみたり、PyPDF2でやってみたりと。
大体上記エラー「IndexError: Accessing nonexistent PDF page number(存在しないPDFページ番号へのアクセス)」で詰まってしまいます。
長い期間考えて、いろいろ試行錯誤して参りましたが、自分の頭では解決する事ができませんでした。
長くなってしまい申し訳ありませんが、知恵をお借りできれば幸いです。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ソースコードとエラーメッセージを見る限りでは、探索中のディレクトリ直下にjpgファイルがない場合の考慮が不足しているように思われます。

py

1files = glob.glob(os.path.join(cur_dir, f, r"*.jpg")) 2with open(os.path.join(cur_dir, f, f"{f}.pdf"), "wb") as f1: 3 f1.write(img2pdf.convert([file for file in files]))

エラーになっているのは上記の部分ですが、たとえばディレクトリroot/Aを探索している場合、変数filesは空のリストになります (root/A直下にはjpgファイルがないため)。img2pdf.convertは渡された空リストに[0]でアクセスしようとして、IndexErrorになっているのではないかと想像します。

img2pdf.convertを呼び出す前にfilesが空リストになっていないかを判定して、空リストではない場合にimg2pdf.convertを呼び出すコードにした場合、想定通り稼働すると思います。

投稿2021/01/15 04:27

neko_the_shadow

総合スコア2230

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TomF

2021/01/16 02:35 編集

回答ありがとうございます! 確かにjpgファイルがない場合スキップする手順を入れるのを怠っておりました。 見つけて頂きありがとうございます。 しかし、修正しても上手く動きませんでした。具体的には、 if os.path.isdir(os.path.join(cur_dir, f, sf)): の下に ・・・・if not os.path.exists('*.jpg'): ・・・・・・・・continue ・・・・else: と入れてみました。エラーメッセージは表示されなくなったのですが、PDFが出来上がらないんです。 print()で表示してみると何故かフォルダ内の.jpgファイルが無いことになってしまうんです。 原因はなんだかわかりますか?
neko_the_shadow

2021/01/16 02:45

os.path.existsはグロブを扱えないようです。対象のディレクトリに何らかのjpgファイルがあった場合でも、os.path.exists("*.jpg")はFalseを返します。 修正方法はいろいろあると思いますが、例えば以下のようにしてみてはどうでしょうか? files = glob.glob(os.path.join(cur_dir, f, r"*.jpg")) if files: with open(os.path.join(cur_dir, f, f"{f}.pdf"), "wb") as f1: f1.write(img2pdf.convert([file for file in files]))
TomF

2021/01/17 01:17

なるほど!扱える・扱えないもあるのですか。難しすぎです。。 neko_the_shadowさんの通りにやってみたらできました! 自分で解決しようと意気込んで、仕事の合間に1か月ほど調べても解決できなかったのでとても感激です! 質問して良かったです。感謝感謝。 ファイル操作、ひとつ勉強になりました。 本当にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問