python脚本将照片按时间线整理

说明:有一次自己瞎折腾,然后把服务器相册搞崩了,后来做了备份同步给找了回来,但是相册的时间线全乱了,看起来非常难受。所以就想通过文件夹的形式把照片重新分类,分类后的结构如下(红色字体为文件夹):

未分类
2023
├── 202301
│ ├── 图片1.jpg
│ ├── 图片2.jpg
│ └── 图片3.jpg
├── 202302
│ ├── 图片4.jpg
│ ├── 图片5.jpg
│ └── 图片6.jpg
└── …
├── …
├── …
└── …
2024
├── 202401
│ ├── 图片1.jpg
│ ├── 图片2.jpg
│ └── 图片3.jpg
├── 202402
│ ├── 图片4.jpg
│ ├── 图片5.jpg
│ └── 图片6.jpg
└── …
├── …
├── …
└── …

在这里插入图片描述

import os
import shutil
from PIL import Image
from PIL.ExifTags import TAGS

# 定义支持的照片格式
supported_formats = ['.jpg', '.jpeg', '.png', '.bmp', '.gif', '.tiff']


# 获取当前脚本文件的绝对路径
script_path = os.path.abspath(__file__)

# 获取当前脚本文件的所在目录的上级目录
directory = os.path.dirname(os.path.dirname(script_path))

# 脚本所在目录的路径下创建程序处理的照片的根文件夹
done_photos_folder = os.path.join(directory, 'done_photos')
os.makedirs(done_photos_folder, exist_ok=True)

# 创建未归类文件夹
unclassified_folder = os.path.join(done_photos_folder, '未归类')
os.makedirs(unclassified_folder, exist_ok=True)


def process_photos(directory_path):
    # 遍历目录中的所有文件和目录
    for filename in os.listdir(directory_path):
        # 构建完整的文件或目录路径
        path = os.path.join(directory_path, filename)

        if os.path.isfile(path):
            # 获取文件的扩展名
            file_ext = os.path.splitext(filename)[1].lower()

            # 如果文件是照片格式,则读取其信息
            if file_ext in supported_formats:
                process_photo(path)

        elif os.path.isdir(path):
            # 处理子目录中的照片
            process_photos(path)


def process_photo(file_path):
    # 如果file_path包含“done_photos”则不处理
    if "done_photos" in file_path or "photo_demo" in file_path:
        return
    # 打开图片
    image = Image.open(file_path)

    # 获取图片的Exif信息
    exif_data = image._getexif()

    # 默认拍摄时间为未归类
    capture_time = "未归类"

    # 遍历Exif信息
    if exif_data:
        for tag_id, value in exif_data.items():
            # 将标签ID转换为标签名
            tag_name = TAGS.get(tag_id, tag_id)
            # 如果标签名为DateTimeOriginal,则将拍摄时间赋值给capture_time
            if tag_name == 'DateTimeOriginal':
                capture_time = value
                break

    print("照片:", file_path)
    print("拍摄时间:", capture_time)

    if capture_time != "未归类":
        # 提取拍摄年份和月份
        year = capture_time[:4]
        month = capture_time[5:7]

        # 创建年份文件夹
        year_folder = os.path.join(done_photos_folder, year)
        os.makedirs(year_folder, exist_ok=True)
        print("创建年份文件夹:", year_folder)

        # 创建月份文件夹
        month_folder = os.path.join(year_folder, year + month)
        os.makedirs(month_folder, exist_ok=True)
        print("创建月份文件夹:", month_folder)

        # 构建最终存放照片的文件路径
        final_path = os.path.join(month_folder, os.path.basename(file_path))
    else:
        # 未归类文件的存放路径
        final_path = os.path.join(unclassified_folder, os.path.basename(file_path))

    try:
        # 复制照片到相应的文件夹中
        shutil.copy2(file_path, final_path)
        print("复制照片到:", final_path)
    except Exception as e:
        print("无法复制照片:", e)

    print()


if __name__ == '__main__':
    process_photos(directory)

或者直接使用python脚本执行也可以。打包文件photo_demo下photo_demo.exe的可执行文件为pyinstaller photo_demo.py命令打包,不含病毒,如果有报毒请自行斟酌。

注意:代码仅做了简单测试,各位客官按需服用
如果是使用photo_demo打包文件执行,会将photo_demo所在目录作为作为扫描起始目录,即扫描该目录下的所有图片,并在该目录下创建:未分类20XX等分类目录。如果是使用脚本的话请自行调试,比如执行目录改为手动指定等

photo_demo打包文件下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/370439.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

人生百相,不过熵增熵减

这篇博文由两个问题衍生而来,分别是:“为什么除法比加法困难”、“什么是生命进化的目的”。在阅读其他人的解读时,发现都关联到了一个概念,熵。觉得十分有意思,因此记录一下自己的遐想。 熵(Entropy&#…

vulhub中spring的CVE-2022-22965漏洞复现

在JDK 9上运行的Spring MVC或Spring WebFlux应用程序可能存在通过数据绑定执行远程代码(RCE)的漏洞。 现在已知的利用方法要求应用程序以WAR部署的形式在Tomcat上运行,然而,该漏洞的性质更为普遍,可能有其他方法可以利…

docker安装-centos

Docker CE 支持 64 位版本 CentOS 7,并且要求内核版本不低于 3.10 卸载旧版本Docker sudo yum remove docker \ docker-common \ docker-selinux \ docker-engine使用yum安装 yum 更新到最新版本: sudo yum update执行以下命令安装依赖包: sudo yum…

【无刷电机】无感方波驱动方案

无感方波驱动方案 1.通过无感过零信号构造霍尔换相信号2.无刷硬件驱动方案3.无感方波控制程序框架3.1有感方波控制3.2无感方波控制3.3无感启动方案3.4无感速度闭环控制1.通过无感过零信号构造霍尔换相信号 实现无感方波控制有软件比较和硬件比较两种方案。 软件比较是通过ADC采…

张维迎《博弈与社会》威胁与承诺(3)承诺行为

承诺的作用 上一节,我们探讨了如何在求解博弈时把不可置信的威胁或许诺排除出去,从而对参与人的行为做出合理的预测。如前所述,其中一个隐含的前提条件是,参与人要具有理性共识。而理性共识是一个要求很高的条件,现实生…

基于Springboot的校园失物招领网站(有报告)。Javaee项目,springboot项目。

演示视频: 基于Springboot的校园失物招领网站(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构…

基于Springboot的兼职网(有报告)。Javaee项目,springboot项目。

演示视频: 基于Springboot的兼职网(有报告)。Javaee项目,springboot项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构&#xff0…

Oracle喊你领取免费AI 助理级证书啦!

拿证秘籍如下: 1. 登录Oracle的考试中心网站:https://education.oracle.com/certification 2. 选择AI 助理级考试,考试代码:1Z0-1122-23,也可以点击这里直达 3. AI学习视频免费看,也可以选择不看 3.5 去…

【git 本地管理版本及与github合并】 Init Push Pull操作解决方案

文章目录 创建本地仓库,并与远程仓库链接更新本地仓库并使用Push推送到远程仓库 1. 几种基础命令介绍:2. git push操作流程 .gitignore删除本地仓库,断开本地与远程的链接设置用于提交commit的用户名,邮箱,以便githu…

自建服务器监控工具uptime kuma

web服务器使用 雨云 提供的2核2g 这里使用1panel的uptime kuma 首先,如果你使用雨云,那么可以直接省去安装1panel的烦恼 直接选择预装后,等待部署完成即可看到面板信息,进入面板,点击应用商店 在应用商店里找到upti…

安装配置Oracle 11g 、PLSQL及使用Navicat远程连接Oracle

目录 一、下载 二、安装 1.执行安装程序 2.配置安全更新 3.安装选项 4.系统类 5.网络安装选项 6.选择安装类型 7.选择产品语言 8.选择数据库版本 9.指定安装位置 10.选择配置类型 ​编辑11.指定数据库标识符 12.指定配置选项 13.电子邮箱 14.指定数据库存储…

Android学习之路(28) 进程保活组件的封装

前言 远古时代,出现过很多黑科技,比如MarsDaemon,使用双进程守护的方式进行保活,在当时可谓风光无限,可惜在8.0时代到来就被废弃了。 又比如后面出现的1像素Activity的保活方式,说他流氓一点不过分&#…

解决Android camera 录像中拍照帧率不足30fps

问题现象 camera录像中拍照,录出来的视频帧率为29.3fps,未达到30fps。 问题分析 这个场景相当于跑了previevediocapture,极其损耗性能。 当前场景CPU频率已处于最高。 抓取systrace分析。 1,分析掉帧直接原因 SinkNode存在大…

【Leetcode】第 383 场周赛

文章目录 100214. 边界上的蚂蚁题目思路代码结果 100204. 将单词恢复初始状态所需的最短时间 I题目思路代码结果 100189. 找出网格的区域平均强度题目思路代码结果 100203. 将单词恢复初始状态所需的最短时间 II题目思路代码结果 100214. 边界上的蚂蚁 题目 题目链接 给你一个…

容器和镜像

容器和镜像是现代软件开发和部署中重要的概念,它们通常与容器化技术(如Docker)相关联。以下是它们的基本定义和关系: 容器(Container): 容器是一种轻量级、可移植的运行环境,其中包含了应用程序及其依赖项(…

《Python 网络爬虫简易速速上手小册》第5章:Python 数据存储与管理(2024 最新版)

文章目录 5.1 选择数据存储方案5.1.1 重点基础知识讲解5.1.2 重点案例:使用 SQLite 存储博客文章数据5.1.3 拓展案例 1:使用 MongoDB 存储社交媒体动态5.1.4 拓展案例 2:使用 Elasticsearch 存储和检索日志数据 5.2 数据清洗与预处理5.2.1 重…

小林Coding_操作系统_读书笔记

一、硬件结构 1. CPU是如何执行的 冯诺依曼模型:中央处理器(CPU)、内存、输入设备、输出设备、总线 CPU中:寄存器(程序计数器、通用暂存器、指令暂存器),控制单元(控制CPU工作&am…

ShardingSphere 5.x 系列【1】专栏导读

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.1.0 本系列ShardingSphere 版本 5.4.0 源码地址:https://gitee.com/pearl-organization/study-sharding-sphere-demo 文章目录 1. 背景2. 简介3. 适用人群4. 环境…

线程池,定时器以及阻塞队列(生产者/消费者模型)

💓 博客主页:从零开始的-CodeNinja之路 ⏩ 收录专栏:线程池,定时器以及阻塞队列(生产者/消费者模型) 🎉欢迎大家点赞👍评论📝收藏⭐文章 实现线程池,定时器以及阻塞队列,生产者/消费者模型 线程池线程池…

STM32 UART/USART在无线通信模块和蓝牙设备中的应用案例

STM32微控制器与无线通信模块和蓝牙设备的结合,为物联网和无线通信应用提供了广泛的可能性。下面是两个典型的应用案例,展示了STM32的UART/USART与无线通信模块(如Wi-Fi模块)和蓝牙设备的集成。 ✅作者简介:热爱科研的…