尝试重命名家庭照片,我希望此文件夹中的所有照片都重命名为
mmdd__00X
所以 3 月 23 日的第 20 张图像的文件名应该是
0323__020
我的很多代码都来自其他线程,我使用了来自 Python 文件创建日期和重命名 - 请求批评 对于大部分内容,但发现我需要拍摄日期(exif 数据)而不是创建日期。问题是,Pillow 中的 EXIF 模块将拍摄日期标记作为字符串,但我需要它是 int 或 datetime 以便我能够修改。或者我可以解析字符串以适合我的命名格式吗?
import os
import datetime
from PIL import Image
target = input('Enter full directory path: ')
os.chdir(target)
allfiles = os.listdir(target)
counter = 0
def get_date_taken(path):
return Image.open(path)._getexif()[36867]
for filename in allfiles:
t = get_date_taken(filename)
v = datetime.datetime.fromtimestamp(t)
x = v.strftime('%m%d')
y = '{:02d}'.format(counter)
try:
os.rename(filename, x+"__"+y+".jpg")
except FileExistsError:
while True:
try:
counter += 1
y = '{:02d}'.format(counter)
os.rename(filename, x+"__"+y+".jpg")
except FileExistsError:
continue
counter = 0
break
第一个真正的程序,任何帮助将不胜感激。
首先将日期时间字符串解析为时间结构,然后可以根据需要进行格式化:
from PIL import Image
DateTimeOriginal = 36867
for filename in os.listdir('.'):
if isfile(filename) and filename.endswith('.jpg'):
try:
dto_str = Image.open(filename)._getexif()[DateTimeOriginal]
dto = time.strptime(dto_str, '%Y:%m:%d %H:%M:%S')
except (KeyError, TypeError):
print('error: no exif datetime value found for %r.' % filename)
continue
print(filename, dto)
new_filename = time.strftime('…', dto)
# os.rename(filename, new_filename)
更新: 现在 DateTime 支持 fromisoformat(),您还可以使用以下方法解析字符串:
dto = DateTime.fromisoformat(dto_str.replace(':', '-', 2))
好吧,如果您使用的是 Windows,那么您的 try 块中将出现一个
OSError
,并且您的代码将使用以下增强功能(又名 idk 足够了解 .format
的事情)。请参阅下面的os.listdir
建议。
for filename in allfiles:
t = get_date_taken(filename)
v = datetime.strptime(t, 'enter format of t here')
x = v.strftime('%m%d__%H%M%S')+str(counter).zfill(3)+'.jpg'
try:
os.rename(filename, x)
except OSError:
# etc...
此代码也无法在 MacOS 和 Linux 上运行!您将删除很多文件!
os.rename()
如果目标文件与源文件同名,则覆盖目标文件
修复建议如下,但首先
os.listdir
列出了包括子目录在内的所有内容。如果您想要所有文件,请这样做
allfiles = [f for f in os.listdir(target) if os.path.isfile(os.path.join(target, f)]
#...or if you want only jpgs...
allfiles = [f for f in os.listdir(target) if os.path.isfile(os.path.join(target, f) and (f.lower().endswith('.jpg') or f.lower().endswith('.jpeg))]
好的,建议:我建议重命名所有附加整个日期时间的文件(如果您每秒拍摄多张图像,则可以添加微秒)。例如
for filename in allfiles:
t = get_date_taken(filename)
v = datetime.strptime(t, 'enter format of t here')
x = v.strftime('%m%d__%H%M%S')+'.jpg'
os.rename(filename, x)
filename = x
因此,如果一切顺利,
allfiles
是所有重命名文件的列表。排序应该按天为您提供升序或降序的图片,检查哪个并确保列表从最早到最新。
然后使用计数器进行迭代,该计数器在给定日期为每张照片递增,到达新的一天时重置为 0,并用计数器替换文件名的时间部分。时间部分的长度是固定的,你的扩展也是固定的,这样你就可以砍掉最后的部分。
就是这样。由于它会两次遍历您的文件并进行排序,因此需要更长的时间,但我想谨慎行事。这样做的好处是它会按时间组织您的文件。
对上述代码块的改进是,如果在重命名过程中引发异常,则将重命名的文件转换回原始文件名,以便您无需编写新代码即可再次运行代码。这需要保留一个新文件名列表,如下所示:
new_names = []
for filename in allfiles:
v = datetime.strptime(t, 'enter format of t here')
x = v.strftime('%m%d__%H%M%S')+'.jpg'
try:
os.rename(filename, x)
except:
print 'something went wrong, reverting changes...'
for new, old in zip(new_names, allfiles[:len(new_names)]):
os.rename(new, old)
raise
else:
filename = x
new_names.append(x)