Chinaunix首页 | 论坛 | 博客
  • 博客访问: 379762
  • 博文数量: 26
  • 博客积分: 522
  • 博客等级: 中士
  • 技术积分: 329
  • 用 户 组: 普通用户
  • 注册时间: 2009-04-14 13:49
文章分类

全部博文(26)

文章存档

2015年(2)

2012年(7)

2011年(16)

2009年(1)

我的朋友

分类: Python/Ruby

2015-09-18 11:08:58

最开始的参照python脚本网页找不着了,没法给人家一个说法
这个批量修改照片名称的脚本是根据我自身情况重构的,也算是我的劳动成果吧。在此分享给大家。
如果大家在网上搜到不同批量修改照片名的脚本,但里面又有相同的函数,你不要怀疑,肯定他的是原版。
嘻嘻。。。。

点击(此处)折叠或打开

  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. '''
  4. 批量修改照片文件名称的Python脚本程序。
  5. 遍历指定目录(含子目录)的照片文件,根据拍照时间将照片文件名修改为以下格式:
  6. 2014-03-15_09-12-30_xxxx.jpg (%Y-%m-%d_%H-%M-%S_random<4>)

  7. 考虑到处理的文件可能来自不同设备,理论上有拍摄时间相同的概率,
  8. 所以在根据文件拍摄时间重命名的时候,在文件名结尾加上4位随机码,
  9. 如果需要考虑到重名的问题,可以对本程序进行进一步的优化。

  10. Author: ****
  11. Date: 2015-09-15

  12. !该程序需要安装exifread模块,否则无法使用。
  13. 例如,Linux/Mac OS X下命令行安装该模块:sudo pip install exifread
  14.      Windows 下cmd命令行安装该模块 d:> easy_install exifread
  15. '''

  16. import os
  17. import stat
  18. import time
  19. import exifread
  20. import shutil
  21. import random

  22. SUFFIX_FILES = ['.jpg','.png','.mpg','.thm','.bmp','.jpeg','.avi','.mov','.mp4']

  23. def isTargetedFileType(filename):
  24.     '根据文件扩展名,判断是否是需要处理的文件类型'
  25.     f,e = os.path.splitext(filename)
  26.     if e.lower() in SUFFIX_FILES:
  27.         return True
  28.     else:
  29.         return False

  30. def getRandom():
  31.     '获取4位随机数'
  32.     #文件末尾加上随机数可能会有如下情况,各位酌情使用
  33.     # 1)同一张照片可以无限制存储在同一个目录下
  34.     # 假如同一张照片在不同位置都有保存,通过这个脚本是没法区分的
  35.     # 因为即使拍摄时间相同但随机数不同,脚本还是认为是不同的照片
  36.     # 2)不同设备在同一时间点拍摄的照片会被当成同一张照片
  37.     # 假如不同设备在同一时间点拍摄照片,如果不加随机数,根据拍摄时间,脚本是没法区分照片的不同的
  38.     # 注:这种情况也可以在文件名中加上exif其他信息,以区分来自不同拍摄设备的照片
  39.     list = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e']
  40.     return ''.join(random.sample(list, 4))

  41. def getTargetedFileExifDateTime(filename):
  42.     'Read Exif metadata form tiff and jpeg files.'
  43.     try:
  44.         # Open image file for reading (Binary mode)
  45.         f = open(filename, 'rb')
  46.     except Exception, ex:
  47.         print 'OpenFileError: %s' % ex

  48.     # Return Exif tags
  49.     try:
  50.         tags = exifread.process_file(f)
  51.     except Exception, exe:
  52.         #print 'exifread.process_file: %s' % exe
  53.         tags = {}

  54.     # 返回文件的拍摄时间
  55.     # 获取照片中exif时间信息的任意一个时间
  56.     if tags.has_key('EXIF DateTimeOriginal'):
  57.         dt = tags['EXIF DateTimeOriginal']
  58.         key = 'EXIF DateTimeOriginal'
  59.     elif tags.has_key('EXIF DateTimeDigitized'):
  60.         dt = tags['EXIF DateTimeDigitized']
  61.         key = 'EXIF DateTimeDigitized'
  62.     elif tags.has_key('Image DateTime'):
  63.         dt = tags['Image DateTime']
  64.         key = 'Image DateTime'
  65.     else:
  66.         dt = None
  67.         key = None
  68.     print '%-25s\t[%s] => [%s]' % (filename, key, dt)
  69.     return dt

  70. def generateNewFileName(filename):
  71.     '''
  72.        一、根据是否能获取到文件拍摄日期,将文件存储在不同的目录下
  73.           1. 获取到拍摄日期,文件存储路径为 照片/年/月/日
  74.           2. 未取得拍摄日期,根据文件的创建日期,将文件存储路径为 未分类/年/月/日
  75.     '''

  76.     #标记是否获取到文件拍摄时间
  77.     #如果不想文件分<照片/未分类>目录存放,将标记位值为True
  78.     #isGetTargetedFileExifDateTime = True
  79.     isGetTargetedFileExifDateTime = False
  80.     #取得文件的名称和后缀
  81.     f,e = os.path.splitext(filename)
  82.     #取得文件的拍摄时间
  83.     fileDateTime = getTargetedFileExifDateTime(filename)
  84.     #取得随机数
  85.     fileSuffixRandom = getRandom()

  86.     if fileDateTime:
  87.         #获取到拍摄时间,将标识位值为True
  88.         isGetTargetedFileExifDateTime = True
  89.         #转换成 yyyy-mm-dd_hh-mm-ss_xxxx的格式
  90.         #获取到拍摄日期的文件,按照文件的拍摄 年//日 目录存储
  91.         filePrefix = str(fileDateTime).replace(":","-")[:10] + "_" + str(fileDateTime)[11:].replace(":","-") + "_" + fileSuffixRandom
  92.         DirSuffix = str(fileDateTime)[:4] + os.sep + str(fileDateTime)[5:7] + os.sep + str(fileDateTime)[8:10]
  93.     else:
  94.         #本想在文件没有取得拍摄日期时,直接将文件保存在指定默认目录<未分类>
  95.         #因为我情况是有好多照片是从网上下载下来
  96.         #如果要将这些文件重命名,只能根据创建时间(即下载到设备的时间),但这又是不准确
  97.         #文件名原样保存
  98.         #filePrefix = f
  99.         #DirSuffix = None
  100.         #################没有获取到拍摄日期的文件,保存在指定目录下##########################
  101.         #如果没有取得exif信息,则用对象文件的修改日期作为拍摄日期
  102.         objState = os.stat(filename)
  103.         filePrefix = time.strftime("%Y-%m-%d_%H-%M-%S", time.localtime(objState[-2])) + "_" + fileSuffixRandom
  104.         DirSuffix = str(filePrefix)[:4] + os.sep + str(filePrefix)[5:7] + os.sep + str(filePrefix)[8:10]
  105.         #############################################################################

  106.     #配置文件的存储路径
  107.     #重命名的文件存储路径前缀任意定义
  108.     if isGetTargetedFileExifDateTime:
  109.         storeDir = u'D:\\影像备份\\照片' + os.sep + DirSuffix
  110.     else:
  111.         storeDir = u'D:\\影像备份\\未分类' + os.sep + DirSuffix
  112.        
  113.     #检测文件存储路径是否存在
  114.     if not os.path.isdir(storeDir):
  115.         os.makedirs(storeDir)

  116.     #合并新文件名称及存储路径
  117.     newFileName = os.path.join(storeDir , filePrefix + e).lower()
  118.     return newFileName

  119. def scandir(startdir):
  120.     '遍历指定目录以及子目录,对满足条件的对象进行改名移动'
  121.     if not os.path.isdir(startdir):
  122.         raise "你访问的目录不存在."
  123.     os.chdir(startdir)
  124.     for obj in os.listdir(os.curdir):
  125.         if os.path.isfile(obj) and isTargetedFileType(obj):
  126.             #对满足过滤条件的文件进行改名处理
  127.             newFileName = generateNewFileName(obj)
  128.             #对于重命名的文件加上4位随机数,下面这句if判断是多余的
  129.             #在文件量不是很大的情况下,因为不可能存在拍摄时间和随机数都相同的文件名,暂且保留这句吧!
  130.             if not os.path.isfile(newFileName):
  131.                 print "move [%s] => [%s]" % (os.getcwd().decode('gbk') + os.sep + obj, newFileName)
  132.                 shutil.move(obj, newFileName)
  133.             else:
  134.                 pass
  135.         elif os.path.isdir(obj):
  136.             scandir(obj)
  137.             os.chdir(os.pardir)
  138.         else:
  139.             pass

  140. if __name__ == "__main__":
  141.     path = u"D:\\影像备份"
  142.     scandir(path)

阅读(3610) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~