1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

PythonでJPG/PNG→PDF変換

Posted at

お題

オタ活に勤しんでいる娘がダウンロードした推しの画像をローソン等でプリントしてポスターやらウチワやら缶バ1やら作るのにいちいち変換してくれるサイト2でPDFに変換しているようです。そんな面倒なことをせずとも前回のように自分のPCだけで完結するやんという話をしましてまた別のコンバータを作ることになりました。
今回はJPG/PNG→PDF変換になります。
尤もわざわざPDFに変換したものをマルチコピー機でPDFプリントしなくても自宅PCからネットワークプリントで先にアップロードだけしておけばいいようなものですが、PDFプリントのA3カラーは80円でネットワークプリントのA3カラーは100円なのです。また、ネットワークプリントではJPGとPDFは印刷可能ですがPNGはダメなようです。

開発環境

  • OS:Windows10Home(1903)
  • Editor:Visual Studio Code
  • Python:3.8.3

調べてみた

「python jpg pdf」でググるとどうやらimg2pdfというライブラリを使えば変換できるらしいので早速導入。

> pip install img2pdf

また、画像を扱うためPIL(Python Imaging Library)も必要なので調達。

> pip install pillow

なぜpillow(枕)なのかは不明。

コード

Image2PDF.py
import sys
import os
import img2pdf
from PIL import Image

def RemoveAlpha(src):
    dstPath = os.path.dirname(src)
    dstName = os.path.basename(src)
    dstPNG = os.path.join(dstPath, "_" + dstName)
    img = Image.open(src)
    img = img.convert("RGB")
    img.save(dstPNG)

    return dstPNG

if __name__ == "__main__":
    srcOrgImage = sys.argv[1]
    print(f"IN:{srcOrgImage}")

    srcExt = os.path.splitext(os.path.basename(srcOrgImage))[1]
    dstPath = os.path.dirname(srcOrgImage)
    dstName = os.path.splitext(os.path.basename(srcOrgImage))[0]
    dstPdf = os.path.join(dstPath, f"{dstName}.pdf")
    print(f"OUT:{dstPdf}")

    if srcExt.upper() == ".PNG":
        srcImage = RemoveAlpha(srcOrgImage)
    else:
        srcImage = srcOrgImage

    with open(dstPdf, 'wb') as f:
        f.write(img2pdf.convert(srcImage))

    if srcOrgImage != srcImage:
        os.remove(srcImage)

構想としては前回と同じようにデスクトップ上のショートカットに変換したいファイルをD&Dすると同じフォルダに.pdfを生成するものです。今回もパス周りの処理が延々とあってヤボったいですが。
いくつかの画像ファイルの変換を試していると.jpgでは問題ありませんでしたが.pngファイルの場合にアルファチャンネルを含んでいるPNGはPDFに変換できないとエラーになったのでRemoveAlpha()でRGBA→RGBとして一時ファイルに保存、それを入力ファイルとしてPDF変換させています。

運用

で、今回も起動用のバッチファイルを用意してめでたし。

Image2PDF.bat
@echo off
py Image2PDF.py %1

だがしかし・・・

前回の続きになりますがフォルダ名・ファイル名に全角スペースが含まれている場合にD&Dで正しいフルパスが取得できない問題。調べてみると全角スペース以外にもアウト判定な文字があるようです。例えばちょっと細工して

argvTest.bat
@echo off
py argvTest.py %1 %2 %3 %4 %5 %6 %7 %8 %9
argvTest.py
import sys

if __name__ == "__main__":
    len = len(sys.argv)
    print(f"len={len}")

    for i in range(len):
        print(sys.argv[i])

これに「C:\Tmp\aaa bbb ccc.txt」(全角スペース入り)を喰わせると

len=3
argvTest.py
C:\Tmp\aaa
bbb
ccc.txt

となるのでぶった切られた文字が全角スペースとわかっているのであればargv[1]以降を最後まで全角スペースを挟んでjoinしてやればなんとかできそうですが、ぶった切られる文字の候補が複数あってしかもその情報はもう失われているので復元は無理かなと。
でもこれが今回のようにバッチファイル経由で動かすPythonではなく.exeのショートカットに対してD&Dすると特にぶった切られることなく一つの文字列として取得できます3
つまりWindowsのコマンドプロンプト4がイケてない?ですかね。

  1. 缶バッジ

  2. Canvaとか

  3. .exeと言えど上記Python版と同様にバッチファイルから呼び出すと同じ結果になります

  4. cmd.exe

1
1
0

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?