とっちゃん@nyanco! です。
今回は複数の画像(フォルダでもOK)をドラッグ&ドロップしたら縦長画像と横長画像で自動でフォルダ分けしてくれるというPythonコードの共有です。
縦横比を見て自動仕分けしてくれますにゃ~
ファイルをコピーするので元の画像ファイルに影響はないですにゃ~
出力結果は必ず内容をチェックしてください。本記事で紹介するスクリプトの使用は自己責任でお願いいたします。
コードの動作環境
- OS:Windows10 ※macOSでは未確認
- Pythonバージョン:3.11.2
- 必要ライブラリ:
- opencv-python (cv2)
- numpy
- tkinter (通常はPythonに標準で含まれています)
- tkinterdnd2
必要ライブラリをまとめてインストールするコードは以下となります(すでにインストール済みのライブラリがあってもOK)。
pip install opencv-python numpy tkinterdnd2
何ができるコードか解説
まず、何ができるコードなのかを動画でご紹介します。
縦長画像は「tate」、横長画像は「yoko」フォルダへ自動仕分けするだけのシンプルなスクリプトですにゃ~
シンプルな動作ですが、たくさんの画像で同じことを手動でやろうとすると意外と面倒臭い&時間がかかるのでニッチなニーズにマッチした方は、是非お試しください。
【対応画像ファイルフォーマット】png、jpg、jpeg、gif、bmp、heic
複数画像をD&Dしたら縦横比率でフォルダ分けしてくれるコード
早速ですがコードはこちら!
import os
import shutil
import cv2
import numpy as np
import tkinter as tk
from tkinter import messagebox
from tkinter import filedialog
from tkinterdnd2 import DND_FILES, TkinterDnD
def process_image(file_path, tate_folder, yoko_folder):
filename = os.path.basename(file_path)
if filename.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp', '.heic')):
try:
img = cv2.imdecode(np.fromfile(file_path, dtype=np.uint8), cv2.IMREAD_COLOR)
if img is None:
print(f"警告: {filename} を読み込めませんでした。スキップします。")
return
height, width = img.shape[:2]
if height > width:
dest_folder = tate_folder
print(f"{filename} を tate フォルダにコピーします。")
else:
dest_folder = yoko_folder
print(f"{filename} を yoko フォルダにコピーします。")
# 同名ファイルが存在する場合、名前を変更してコピー
dest_path = os.path.join(dest_folder, filename)
counter = 1
while os.path.exists(dest_path):
name, ext = os.path.splitext(filename)
new_filename = f"{name}_{counter}{ext}"
dest_path = os.path.join(dest_folder, new_filename)
counter += 1
shutil.copy2(file_path, dest_path)
print(f"{filename} をコピーしました。")
except Exception as e:
print(f"エラー: {filename} の処理中に問題が発生しました。 - {str(e)}")
def process_folder(folder_path):
tate_folder = os.path.join(folder_path, 'tate')
yoko_folder = os.path.join(folder_path, 'yoko')
# フォルダが存在しない場合は作成
os.makedirs(tate_folder, exist_ok=True)
os.makedirs(yoko_folder, exist_ok=True)
for root, dirs, files in os.walk(folder_path):
# 'tate' と 'yoko' フォルダをスキップ
if 'tate' in dirs:
dirs.remove('tate')
if 'yoko' in dirs:
dirs.remove('yoko')
for file in files:
file_path = os.path.join(root, file)
process_image(file_path, tate_folder, yoko_folder)
def process_input(input_path):
if os.path.isfile(input_path):
folder_path = os.path.dirname(input_path)
tate_folder = os.path.join(folder_path, 'tate')
yoko_folder = os.path.join(folder_path, 'yoko')
os.makedirs(tate_folder, exist_ok=True)
os.makedirs(yoko_folder, exist_ok=True)
process_image(input_path, tate_folder, yoko_folder)
elif os.path.isdir(input_path):
process_folder(input_path)
def on_drop(event):
paths = root.tk.splitlist(event.data)
for path in paths:
process_input(path)
messagebox.showinfo("完了", "画像の分類が完了しました。")
def select_input():
path = filedialog.askdirectory()
if path:
process_input(path)
messagebox.showinfo("完了", "画像の分類が完了しました。")
# GUIの設定
root = TkinterDnD.Tk()
root.title("画像仕分けツール")
root.geometry("300x200")
label = tk.Label(root, text="フォルダまたは画像を\nここにドラッグ&ドロップ\nまたは下のボタンをクリック")
label.pack(pady=20)
button = tk.Button(root, text="フォルダを選択", command=select_input)
button.pack(pady=10)
# ドラッグ&ドロップの設定
root.drop_target_register(DND_FILES)
root.dnd_bind('<<Drop>>', on_drop)
root.mainloop()
コードは自動生成AI「perplexity」で作成したものを少しカスタマイズしています。
▼サクッとすぐに使えるように下記より.pyファイルのダウンロードも可能です(zip圧縮しています)。
→複数画像をD&Dしたら縦横比率でフォルダ分けしてくれるコードをダウンロード
使い方
簡単に使い方を解説します。
▼まずは.pyファイルをダブルクリックで実行します。実行するとこのように黒いウィンドウと「画像仕分けツール」という小さなウィンドウが表示されます。
▼続いて「画像仕分けツール」ウィンドウに複数画像(またはフォルダ)をドラッグ&ドロップします。
▼「画像の分類が完了しました」と表示されたら完了です。入力元である画像ファイルがあるディレクトリに「tate」「yoko」フォルダが自動生成され、縦長画像は「tate」フォルダへ、横長画像は「yoko」フォルダへコピーされているのが確認できたらOKです。
おわりに
本記事がどなたかの参考になれば幸いです。
今回は以上となります。
最後まで読んでいただきましてありがとうございました!
それではまた〜✧٩(ˊωˋ*)و✧
コメント