【Python】複数の画像を一気にトリミングするスクリプトを作った話

1318 語
7 分
【Python】複数の画像を一気にトリミングするスクリプトを作った話

はじまり#

リサちゃん avatar
リサちゃん
はあ~、最近髪伸びてきたなあ、切ろっかな~。
135ml avatar
135ml
そういえば、画像を一気に切り抜いてくれるツールを作ったのを思い出したわ! 今回はそのツールを紹介するぜ!
リサちゃん avatar
リサちゃん
おぉ、切ってくれぇ

ツールの紹介#

Anaconda Promptで動かしていきます。

まず、切り抜きたい、トリミングしたい画像たちが入っているフォルダを指定します。

画像がないフォルダを選ぶとスクリプトは何もなく終了です。

1度選んだ範囲で全てトリミングするか、毎回トリミングする範囲を選んでトリミングするかを選びます。今回は「1」にします。(まあ、「1」が出来ることが今回のスクリプトの真骨頂なので。)

表示されているディレクトリがWindowsなのに「/」区切りになっているのが気になりますが、まあ、一旦進んでみましょう。

トリミングした後のファイルを保存するフォルダの名前を入力します。今回は「トリミング後」にします。

入力すると、実際にトリミングする画面になります。画面サイズは決めておらず、縦長の画像なので、最初はこんな風に歪みます。(デフォルトの画面サイズは設定できるんですかねえ? まあ、使えればいいので、これで良いですが。)

画面も縦長にすれば、まあ見れる感じになりました。

そして、下の4つのスライダーを動かすと、実際にトリムする範囲を指定できます。

上限が青の線、下限がオレンジの線、左限が緑の線、右限が赤の線です。

範囲を選んだら、ウインドウを×ボタンで閉じます。

すると・・・・、できない!!!

なぜ、できないんだ~。っていう過程はとりあえず置いておきます。実はここが日本語になってるのが原因だったりします。

直して正常に動いたものが以下になります。「このディレクトリを見て確認してね。」的なメッセージが出てきて、トリミングした画像たちも保存されています。

気をつけたところ#

ここでは、ソースを組むに当たって気をつけたところを記載しています。

ディレクトリをWindowsの「\」で区切る。#

以下、ソースの抜粋部分です。

def DecideNowDir():
'''
nowDir : String absolutely directory default folder
nowDirPath : String absolutely path selected folder
'''
nowDir = os.path.abspath(os.path.dirname(__file__))
nowDirPath = filedialog.askdirectory(initialdir=nowDir)
# Discrimination whether Windows or Mac.
pf = platform.system()
if pf == 'Windows': # OS is Windows
nowDirPath = nowDirPath.replace('/', '\\')
print("Folder's Absolutely Path: {quotation}{folderpath}{quotation}".format(quotation='"',folderpath=nowDirPath))
return nowDirPath

該当箇所は、filedialog.askdirectory()の部分で、これで選択されたファイルのディレクトリはなぜかWindowsでもMacでも”/”区切りとなってしまうみたいなのです。

それで、後続処理に問題が出るかどうかは調べていませんが、どうにも気持ち悪いのでWindowsで動かした時は文字の置換処理が動くようにしています。

ディレクトリに日本語が入っていると処理を行わずに強制終了させる。#

以下、ソースの抜粋部分です。

def TrimImage(trimmed_img_ext):
'''
folderList : List of file filtered with extension in the selected folder.
selectTimes : String of times to input.
extracted_dir : String absolutely path of directory has selected file.
img : Dictionary of pixels of image. (img [height] [width] [color channel])
trimmed_img : Dictionary of pixels of image.
trimmed_img_ext : String of extension of trimmed_img.
trimmed_img_name : String of filename of trimmed_img.
'''
fileList = FileListGetter.GetFileList(DirEditor.DecideNowDir(),trimmed_img_ext)
# Error Handling
if len(fileList) == 0:
print('\nImageEditor exits because of no target files.')
sys.exit(0)
# Error Handling
checkStr = re.compile('[\\a-zA-Z0-9\-\_\.\-\s\:\~\^\=]+')
if checkStr.fullmatch(fileList[0]) == None:
print('\nImageEditor exits because of the directory containing shift-jis character.')
sys.exit(0)
selectTimes = input('What times do you choosing? ("1" or "every"): ')
while selectTimes != '1' and selectTimes != 'every':
selectTimes = input('Retry. ("1" or "every"): ')
extracted_dir = DirEditor.MakeDirectory(fileList[0])

2個目の「Error Handling」の部分になります。

僕も、この記事を書くために動かして気づいたのですが、この画像切り抜きに使用しているOpenCVというモジュールは、なんと指定したディレクトリに日本語(ちゃんと言うとShift_JIS)が入っていると、画像を読み取れません・・・。

OpenCVを作った人たちは、Shift_JISを文字だと思っていないようです・・・。日本語を文字だと思っていないようです・・・。

この不具合を回避するために、Pillowやnumpyなどのモジュールを使って処理する方法がありましたが、そこまでして日本語を使いたいわけではないので、いっそのこと、このモジュールを使う時には日本語のディレクトリは使用できないようにエラー処理を行わせるようにしました。

実装方法としては、ソース内で正規表現で指定した文字だけで表記されているディレクトリだけを使用できるようにしています。

# Error Handling
checkStr = re.compile('[\\a-zA-Z0-9\-\_\.\-\s\:\~\^\=]+')
if checkStr.fullmatch(fileList[0]) == None:
print('\nImageEditor exits because of the directory containing shift-jis character.')
sys.exit(0)

まとめ#

私は、ファイル名に日本語を一生使わないことを誓った。

おしまい#

135ml avatar
135ml
ディレクトリを「\」で区切る。
リサちゃん avatar
リサちゃん
じゃあ、髪を区切ってくるわ

以上になります!

このツールでトリミングした後は・・・・#

一気にトリミングした複数の画像の重複を除きたい場合は、以下のツールで重複を排除してみてはいかがでしょうか? こちらのツールもPythonで動くものになっています!

また、この前段として、以下の記事もあります。

記事を共有

この記事が役に立ったなら、ぜひ他の人と共有してください!

【Python】複数の画像を一気にトリミングするスクリプトを作った話
https://endorphinbath.com/posts/trim-multiple-images/
著者
kinkinbeer135ml
公開日
2021-11-01
ライセンス
CC BY-NC-SA 4.0
Profile Image of the Author
kinkinbeer135ml
SIerをやめて、プログラミングを勉強しています。※Amazonアソシエイトに参加しています。
お知らせ
私のブログへようこそ!これはサンプルのお知らせです。
音楽
カバー

音楽

再生中なし

0:00 0:00
歌詞なし
カテゴリ
タグ
サイト統計
記事
287
カテゴリー
8
タグ
93
総文字数
486,174
運用日数
0
最終活動
0 日前

目次