吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 288|回复: 8
上一主题 下一主题
收起左侧

[Python 原创] 整理大量照片的小工具

  [复制链接]
跳转到指定楼层
楼主
ssdreamC 发表于 2024-11-27 15:50 回帖奖励
本帖最后由 ssdreamC 于 2024-11-27 15:52 编辑

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


昨天写的,后来想着加一下视频和音频的
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("<Enter>", lambda event: self.show_tooltip(event, self.audio_check))
        self.audio_check.bind("<Leave>", self.hide_tooltip)
        self.image_check.bind("<Enter>", lambda event: self.show_tooltip(event, self.image_check))
        self.image_check.bind("<Leave>", self.hide_tooltip)
        self.video_check.bind("<Enter>", lambda event: self.show_tooltip(event, self.video_check))
        self.video_check.bind("<Leave>", 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()

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
helh0275 + 1 + 1 这是一个有思想的懒人的好工具,哈哈哈...

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

沙发
classSTU00 发表于 2024-11-27 21:28
感觉是我需要的,楼主,可以拿去使用下不?
3#
WJia 发表于 2024-11-27 21:47
4#
wang821399672 发表于 2024-11-27 22:19
5#
CooK1e 发表于 2024-11-27 22:26
可以的&#128077;
6#
gdfs59310 发表于 2024-11-27 22:42
能分享吗?
7#
yzb99312 发表于 2024-11-27 22:54
不错,值得
8#
LQYLHM 发表于 2024-11-27 23:27
正时急需。
9#
pyy52pojie 发表于 2024-11-28 02:12
有没有可能加个重复照片检测,自动删除其中一份的功能。
就怕有的图片是重复的但是md5又不一样,以为压缩过
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-28 02:17

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表