根据Exif的拍摄时间和设备名批量重命名照片

  • 初衷
  • 功能如下
  • 源码如下
  • 说明
  • 下载

初衷

朋友有大量的照片,因为某些原因文件名和实际拍摄时间不一致,而实际拍摄时间存在exif中,所以我想了一下,可以通过读取照片中exif中的拍摄时间来重命名照片。这工具是三个月前写的吧,在朋友后续的试用建议下,加上了三种重命名方式:
第一种:优先判断exif信息是否存在,存在则用exif时间重命名
第二种:exif信息不存在,则进行判断文件名是否包含有时间信息,例如564-201206091615.jpg ,此情况就通过正则提取,重命名为2012-06-09-16-15.jpg
第三种:如果前两种都不满足,则通过读取照片文件在电脑中的创建时间来重命名。

很遗憾,上面说的是原版本,没有窗口,纯命令行,有一些小问题,懒得修复了,也就不放出来了,免得因bug,弄坏大家电脑(代码里有一行是当文件名存在有 . 符号,就替换为- 号),因为没加判断,自己的电脑c盘很多带.号的文件路径全换成-了,导致软件失效。 猜测是在调试时选择照片路径,取消了选择,系统默认返回C盘根目录,导致遍历,把C盘的文件夹的 . 号全换成 -号了。此版本就不放出来了,谅解一下,也不修复了。

所以今天抽空重新弄了一个有窗口的,但只有第一种重命名方式,即exif方式,懒得加其它2种重命名方式了,调调试试再修修用户使用时可能因误操作会出现的bug,搞得写了快三小时,怪自己学艺不精咯。

功能如下

第一:选择照片所在的目录,子目录会自动遍历出照片的绝对路径并显示到列表框。
第二:点击开始重命名,然后耐心等待即可,为了省时间,重命名成功的提示没有写出到黑窗口,只输出因拍摄时间同样(即那种1秒拍了十几张照片的,exif中的时间信息一模一样)而导致重命名失败的提示,此时,会自动加上后缀数字1到50,循环50次重命名,当某次重命名成功,会跳出循环,继续下一个照片重命名(之所以循环50次,就是防止有些用户用设备1秒拍出了50张照片)。
第三:实际使用发现,有些照片的格式不支持读取exif信息,忘记哪些了,jpg和dng支持,其它自测。

源码如下

import exifread
from tkinter.filedialog import *   #别问我怎么不导入os模块就能 重命名,我也不知道,可能这个tkinter模块包含有os了吧,哈哈Files_Names={                      #全局变量,存储照片绝对路径  和  目录路径(即不包含照片名的路径)"all_path":[],"ml_name":""
}def mainapp():     #创建窗体app=Tk()app.title("批量根据exif信息自动重命名照片")Label(app, text="批量根据exif信息自动重命名照片", font=("微软雅黑", 25, "bold")).pack()  # 画标签并设置显示的文字,字体,加粗Listbox(app, name='l_b', bg="#f2f2f2", fg="red").pack(fill=BOTH,expand=True)  # 画列表框并指定名字,方便后续根据名字调用获取Listbox实例,指定背景,前景,显示方式Button(app, text="选择照片路径", command=ui_update).pack(fill=BOTH)  # command指定了当按下按钮,会调用哪个方法Button(app, text="开始Exif命命名", command=rename).pack(fill=BOTH)  # leftapp_width = 500  # 设置窗口宽度app_height = 500  # 设置窗口高度win_width = int((app.winfo_screenwidth() - app_width) / 2)  # 设置窗口距离左上角原点的 宽度  屏幕总宽度-软件窗口宽度  再除2,即软件距离左侧窗口的宽度  转为整数,因为下面geometry只接受字符串型整数win_height = int((app.winfo_screenheight() - app_height) / 2)  # 设置窗口距离左上角原点的 高度  屏幕总宽度-软件窗口高度  再除2,即软件距离顶边的高度  转为整数,因为下面geometry只接受字符串型整数app.geometry("%sx%s+%s+%s" % (app_width, app_height, win_width, win_height))  # 设置窗口显示的宽高度 及 距离原点的长宽度return appdef ui_update():   #此方法用于把照片所有的路径读到 列表框,当点击按钮《选择照片路径》,就会调用此方法list_box = a.children["l_b"]  # 读取出列表框对象list_box.delete(0, END)  # 删除全部列表内容,防止你点了几次《选择照片路径》,重复添加了几次照片。Files_Names["ml_name"]=askdirectory()  #选择照片所在的目录并存到变量里,后面重命名完成后,调用这个变量,显示文件夹出来Files_Names["all_path"]=[]      #把存了照片的绝对路径的变量清空,防止你批量重命名完一个文件夹后(此时没关闭软件),继续使用去选择下一个文件夹来重命名,如果不清空,将会出错,因为残留有上一次批量重命名的路径名。if Files_Names["ml_name"]!="":  #此判断为了防止你点了《选择照片路径》按钮,又不选择文件夹,直接点了取消,此时返回空,就不执行遍历照片功能。Files_Names["ml_name"] += "/"list_name(Files_Names["ml_name"])  # 把选择的目录传入到list_name方法中,进行递归遍历照片文件路径def list_name(ml_name):file_names = os.listdir(ml_name)  # 根据选择的目录列出里面的照片及目录 返回列表if file_names != "":               # 只要返回的照片和目录路径不为空,防止你犯二,选择了一个没有照片的空目录list_box = a.children["l_b"]   # 读取出列表框对象,下面在循环插入路径到列表框要用对象调用for i in range(0, len(file_names)):  # 列表转换为循环数。path = os.path.join(ml_name, file_names[i])  # 把目录名ml_name拼接上文件名file_names[i],获得完整路径。if os.path.isfile(path):   # 如果为真,则是文件list_box.insert(END, path)  # 循环插入文件名到列表框Files_Names["all_path"].append(path)   # 完整的照片路径追加到 全局变量列表中else:  # 如果不是文件,那应该是目录,就加上/,再调用自身方法,进行递归列出下一层的文件,很多人在递归这里搞不明白。。。try:list_name(path + "/")except:print("访问目录出错,可能不是一个目录,或者是奇奇怪怪的文件名")def rename():for index,j_file_name in enumerate(Files_Names["all_path"]):  #准备循环重命名with open(j_file_name, 'rb') as f:  # 打开照片文件并读取到f中tags =exifread.process_file(f)  # 从f中通过exifread.process_file获取exif信息(返回一个字典类型)image_exif_time=""   #清空exif拍摄时间信息,为下一个照片重命名做准备,不残留上一个照片的拍照时间image_Make_mode=""   #清空exif拍摄时间信息,为下一个照片重命名做准备,不残留上一个照片的手机型号if "EXIF DateTimeOriginal" in tags.keys():   #如果这个存着拍摄时间的键 存在 上面取出的exif字典里image_exif_time=tags["EXIF DateTimeOriginal"]  #把时间取出来,赋值给变量,准备拿它来当新文件名,下面两个同样道理,都是存着时间的,当判断这个键不存在时,就判断下面两个键有没有时间存着。elif "EXIF DateTimeDigitized" in tags.keys():    #实践发现,这也是一个拍摄时间image_exif_time = tags["EXIF DateTimeDigitized"]elif "Image DateTime" in tags.keys():             #实践发现,这也是一个拍摄时间image_exif_time = tags["Image DateTime"]if ":" in str(image_exif_time):  #取出来的拍摄时间是 2020:01:01 18:18 这种形式,难看image_exif_time = str(image_exif_time).replace(":", "-")  #换成2020-01-01 18-18 形式if "Image Make" in tags.keys() and "Image Model" in tags.keys() :  #如果存在品牌和 型号,就取出来image_Make_mode="-"+str(tags["Image Make"])+str(tags["Image Model"])if image_exif_time!="":  #如果有拍摄时间,就进行 拆分目录 和 文件名img_path="/".join(j_file_name.split("/")[0:-1])  #取出照片目录    D:/ZM/2019.05.11社团周年庆img_name=j_file_name.split("/")[-1]              #取出文件名。    656566.jpghz=img_name.split(".")[-1]                         #取出后缀。     .jpgelse:  #如果没有拍摄时间,直接跳到循环尾,进行下一个照片exif时间的提取,不进行重命名了。continuetry:  # try一下,防止出现未知错误    这里要注意,不能写在with里,因为会占用照片文件,导致重命名失败。new_file_name = ("%s/%s%s.%s") % (img_path, image_exif_time, image_Make_mode, hz)os.renames(j_file_name, new_file_name)except:  # 当出现未知错误,或者是照片里的exif拍摄时间重复,比如1秒拍了10张,这类照片因为时间一模一样,重命名不了,只能在时间一样的照片后面按顺序加上 数字 来重命名。for o in range(50):  # 防止你相机设备太牛逼,1秒拍了50张,导致时间一模一样的照片,所以设置循环50次,在文件名后面依次加上数字来重命名。try:new_file_name = ("%s/%s%s-%s.%s") % (img_path, image_exif_time, image_Make_mode, str(o+ 1), hz)print("第%d张图片重命名中,疑似名字重复或照片文件损坏,重命名失败,将添加后缀%s继续重命名!50次内若重命名还是失败,将忽略些图片!" % (index, str(o + 1)))print("原文件名:%s" % j_file_name)print("预计新文件名:%s\n\n" % new_file_name)os.renames(j_file_name, new_file_name)break  # 当重命名成功后,立即跳出循环,不用笨笨的循环到50次。except:passos.startfile(Files_Names["ml_name"])   #所有文件重命名完成后,弹出照片所有的窗口print("重命名完成!")
a=mainapp()
a.mainloop()

说明

本文非原创,来源于:https://www.52pojie.cn/thread-1253408-1-1.html

下载

https://download.csdn.net/download/s19831024/18583107

Python练习小工具——根据Exif的拍摄时间和设备名批量重命名照片相关推荐

  1. python批量改名微信视频软件,python利用文件时间批量重命名照片和视频

    本文实例为大家分享了python利用文件时间批量重命名照片和视频的具体代码,供大家参考,具体内容如下 问题描述 承接上节的问题,在安卓和苹果间互导照片和视频还容易出现文件名混乱的问题,如下图所示. 代 ...

  2. (批处理)批量重命名照片为拍摄时间后加序号?

    在不同盘下不同文件夹下有许多照片.有许多是重名的.现在想让这些文件重命名为照片拍摄日期外加照片两字,然后是序号.请问怎么实现?批处理最好,不行的话就是插件或工具,请给个下载地址. 例:原文件 名 照片 ...

  3. WPS-js宏 写一个批量重命名的工具宏

    js宏练手小工具--批量重命名 效果展示: 已把写好的宏加在快捷访问工具栏中(上一篇有教程),这里写了一个集合多个工具的窗体,这里直接选择批量重命名. (1)点击'选择文件'按钮选择一个或多个文件' ...

  4. 用Python编写小工具下载OSM路网数据

    文章来源于Python大数据分析,作者费弗里 本文对应脚本已上传至Github仓库: https://github.com/CNFeffery/DataScienceStudyNotes[1] 1 简 ...

  5. python 处理数据小工具_用Python这个小工具,一次性把论文作图与数据处理全部搞定!...

    原标题:用Python这个小工具,一次性把论文作图与数据处理全部搞定! 一入科研深似海-- 随着大学纷纷开学,"防脱发用生姜还是黑芝麻?", 研究僧们又开始为自己所剩无几的头发发愁 ...

  6. 有关Python的小工具 - picture

    有关Python的小工具 - picture 读取图片 通过cv2.imread读取图片 通过cv2.imread读取比特流 通过Image.open读取图片 通过io.BytesIO读取比特流 保存 ...

  7. 【python应用】 文件名称批量重命名工具

    [python应用] 文件名称批量重命名工具 1.背景 2.代码 3.打包 4.使用方法 5.资源 1.背景 参考[python应用] 视频捕获及保存工具 https://blog.csdn.net/ ...

  8. 计算机给文件重命名快捷键,实用电脑小技巧:批量重命名文件常用的小工具也可以设快捷键...

    沪江小编:对于很多人来说,电脑应该算是使用频率最高的工具了,可是你真的会用电脑么?实用电脑小技巧,用最简单明了的方式给你无比有趣的电脑使用新体验. [视觉遗像]注视图形中央的四个黑点30秒,然后闭眼仰 ...

  9. Python课程作品设计——基于EXCEL的批量重命名工具

    基于EXCEL的批量重命名工具 import os,pandas,tkinter,tkinter.messagebox from tkinter import *class AR_GUI():def ...

  10. c++批量重命名_手把手教你用Python批量给图片添加水印 | 知了干货分享

    我们在网上浏览一些文章的时候,经常会发现文章中会有一些图片,上面会有一些标识,而这些标识就是我们经常说的水印了.很多时候,我们需要给图片加上一些修饰,好让别人能直观的认识到这个图片的出处以及来源,同时 ...

最新文章

  1. R语言使用ggplot2包使用geom_density()函数绘制基础密度图实战(density plot)
  2. python模块 init py_Python模块包中__init__.py文件的作用
  3. kotlin自定义View出现 java.lang.ClassNotFoundException
  4. Spring MVC源码——Root WebApplicationContext
  5. 【数据结构与算法】二叉堆V2.0的Java实现
  6. jsp mysql模板_jsp的分页查询的代码(mysql数据库)
  7. 福特新CEO“泼冷水”,给自动驾驶设立商业化节点是否真的有必要?
  8. zabbix分布式监控部署proxy安装
  9. 使用Maven导出war包
  10. springboot2.0 图片收集
  11. 【读书笔记】【独立思考】2018-04-03(2)
  12. 王晓耕老师-风险管理专家
  13. 感觉中国程序员前景一片灰暗,是这样吗?Android开发工程师为你答疑解惑
  14. 敏捷开发 建立愿景、使命_使用愿景板创建敏捷产品策略的10条技巧
  15. itextpdf查找关键字坐标,以及在特定位置添加文字
  16. 【Leetcode】| Largest Number
  17. SQL Server AlwaysOn可用性及故障转移
  18. Sqoop导入导出基本操作
  19. 微信小程序中使用Less
  20. 兮°Android下的屏幕适配问题的一点心得

热门文章

  1. 马氏距离 结合 卡方分布 异常点检测
  2. 计算机专业大学排名及本科录取分数线,计算机专业高考多少分录取?附中国计算机专业大学排名及分数线...
  3. 【C语言基础】-九条语句
  4. sqlserver 中isnull(Null,0) 和isnull(' ',0) 区别
  5. PS--给图片加水印技巧
  6. ORA-20011KUP-11024ORA-29913
  7. 量子物理与计算机,量子物理学的重要应用,与普通计算机结构完全不同,还需继续探索...
  8. 莫 言------------- 我们的荆轲
  9. 数电(二)—分析/画逻辑电路图
  10. 微分方程matlab绘图,用matlab解微分方程组并作图