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



ツールの紹介
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 HandlingcheckStr = 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)まとめ
私は、ファイル名に日本語を一生使わないことを誓った。
おしまい


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

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

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