整理大量照片的小工具

查看 20|回复 2
作者:ssdreamC   
这两天用华为手机助手把手机上的几千张照片导出到了电脑上,想整理一下,但整理起来心态就不太好了,,,
于是拿 python 做了个小工具,按“年月”整理到不同文件夹中,自我感觉还挺好,发上来请大佬们给指导指导{:1_893:}


image.png (31.6 KB, 下载次数: 0)
下载附件
2024-11-27 15:23 上传



image.png (20.3 KB, 下载次数: 0)
下载附件
2024-11-27 15:23 上传



image.png (25.86 KB, 下载次数: 0)
下载附件
2024-11-27 15:22 上传

昨天写的,后来想着加一下视频和音频的
import os
import shutil
from PIL import Image
from PIL.ExifTags import TAGS
from tkinter import Tk, Button, Label, filedialog, Checkbutton, Text, Scrollbar, BooleanVar, Frame, END
class MediaOrganizer:
    def __init__(self, root):
        self.root = root
        self.root.title("Media Files Organizer")
        self.selected_folder = None
        self.tmp = ""
        self.create_widgets()
    def create_widgets(self):
        # 创建Frame来组织复选框和按钮
        control_frame = Frame(self.root)
        control_frame.pack(pady=10)
        # 创建选择文件夹的按钮
        select_button = Button(control_frame, text="选择文件夹", command=self.select_folder)
        select_button.pack(side='left', padx=5)
        # 创建复选框
        self.audio_var = BooleanVar()
        self.image_var = BooleanVar()
        self.video_var = BooleanVar()
        self.audio_check = Checkbutton(control_frame, text="声音", variable=self.audio_var)
        self.image_check = Checkbutton(control_frame, text="图片", variable=self.image_var)
        self.video_check = Checkbutton(control_frame, text="视频", variable=self.video_var)
        self.audio_check.pack(side='left', padx=5)
        self.image_check.pack(side='left', padx=5)
        self.video_check.pack(side='left', padx=5)
        # 绑定鼠标事件
        self.audio_check.bind("", lambda event: self.show_tooltip(event, self.audio_check))
        self.audio_check.bind("", self.hide_tooltip)
        self.image_check.bind("", lambda event: self.show_tooltip(event, self.image_check))
        self.image_check.bind("", self.hide_tooltip)
        self.video_check.bind("", lambda event: self.show_tooltip(event, self.video_check))
        self.video_check.bind("", self.hide_tooltip)
        # 创建开始按钮
        start_button = Button(control_frame, text="开始整理", command=self.start_organizing)
        start_button.pack(side='left', padx=5)
        # 创建状态标签
        self.status_label = Label(self.root, text="将所选文件夹中的媒体文件按照年月分别整理到不同文件夹(例如 202411)中\n需要媒体文件包含EXIF信息,仅整理所选文件夹中的文件,不包含子文件夹")
        self.status_label.pack(pady=10)
        # 创建文本框
        log_frame = Frame(self.root)
        log_frame.pack(pady=10, fill='both', expand=True)
        self.log_text = Text(log_frame, height=20, width=80)
        self.log_text.pack(side='left', fill='both', expand=True)
        scrollbar = Scrollbar(log_frame, command=self.log_text.yview)
        scrollbar.pack(side='right', fill='y')
        self.log_text.config(yscrollcommand=scrollbar.set)
    def get_exif_data(self, image_path):
        try:
            image = Image.open(image_path)
            exif_data = image._getexif()
            if exif_data is None:
                return None
            exif = {
                TAGS[k]: v
                for k, v in exif_data.items()
                if k in TAGS
            }
            return exif
        except Exception as e:
            self.log_text.insert(END, f"读取EXIF数据失败: {e}\n")
            self.log_text.see(END)
            self.root.update_idletasks()  # 强制更新界面
            return None
    def get_date_taken(self, exif_data):
        return exif_data.get('DateTimeOriginal', None)
    def organize_photos(self, folder_path, file_types):
        for filename in os.listdir(folder_path):
            if any(filename.lower().endswith(ext) for ext in file_types):
                file_path = os.path.join(folder_path, filename)
                exif_data = self.get_exif_data(file_path)
                if exif_data:
                    date_taken = self.get_date_taken(exif_data)
                    if date_taken:
                        year_month = date_taken[:7].replace(':', '')
                        year_month_folder = os.path.join(folder_path, year_month)
                        if not os.path.exists(year_month_folder):
                            os.makedirs(year_month_folder)
                        shutil.move(file_path, os.path.join(year_month_folder, filename))
                        self.log_text.insert(END, f"移动 {filename} 到 {year_month_folder}\n")
                        self.log_text.see(END)
                        self.root.update_idletasks()  # 强制更新界面
                    else:
                        self.log_text.insert(END, f"没有日期数据的文件: {filename}\n")
                        self.log_text.see(END)
                        self.root.update_idletasks()  # 强制更新界面
                else:
                    self.log_text.insert(END, f"没有EXIF的文件: {filename}\n")
                    self.log_text.see(END)
                    self.root.update_idletasks()  # 强制更新界面
    def select_folder(self):
        self.selected_folder = filedialog.askdirectory()
        if self.selected_folder:
            self.status_label.config(text=f"选择了文件夹: {self.selected_folder}")
    def start_organizing(self):
        if self.selected_folder:
            file_types = []
            if self.audio_var.get():
                file_types.extend(['.mp3', '.wav', '.flac', '.aac'])
            if self.image_var.get():
                file_types.extend(['.png', '.jpg', '.jpeg', '.tiff', '.bmp', '.gif'])
            if self.video_var.get():
                file_types.extend(['.mp4', '.avi', '.mov', '.mkv'])
            self.organize_photos(self.selected_folder, file_types)
            self.status_label.config(text=f"{self.selected_folder} 中的文件整理好了。")
        else:
            self.status_label.config(text="请选择一个文件夹。")
    def show_tooltip(self, event, widget):
        self.tmp = self.status_label.cget("text")
        if widget == self.audio_check:
            self.status_label.config(text="声音文件包括: .mp3, .wav, .flac, .aac")
        elif widget == self.image_check:
            self.status_label.config(text="图片文件包括: .png, .jpg, .jpeg, .tiff, .bmp, .gif")
        elif widget == self.video_check:
            self.status_label.config(text="视频文件包括: .mp4, .avi, .mov, .mkv")
    def hide_tooltip(self, event):
        self.status_label.config(text=self.tmp)
if __name__ == "__main__":
    root = Tk()
    app = MediaOrganizer(root)
    root.mainloop()

文件, 文件夹

classSTU00   

感觉是我需要的,楼主,可以拿去使用下不?
WJia   

成品呢有成品吗
您需要登录后才可以回帖 登录 | 立即注册

返回顶部