作为幼儿园老师,每天都会拍摄大量的一日生活照片,于是手机经常提示“内存不足”。2020年之前,阿夏采用的方法是这样的:
通常是一个月整理一次手机照片。需要一次性新建30个文件夹并手动修改日期,通过目测选择同一天的照片并拖拽,很容易出现照片或文件夹的拖拽错误。搞了几个月整理后,我对这种低效、机械重复感到无比厌烦。
通过近一年时间的研究,在实现我的整理需求过程中,我在CSDN找到了两个能够执行成功的照片分类代码,技术有限,我读不懂代码的含义,不会修改,只能完全套用。因此在实际运用中,它们展现了长处,也出现了我难以破解的短板。
(1)第一个:
这是我第一个使用的照片整理代码,它可以将照片从源文档复制到新文档,问题是:1、可以转移照片,但无法转移视频。2、原文档不删除
(2)第二个:
在前者基础上,我找到了可以删除原文档、并且转移照片和视频的程序,问题是:1、我不需要日期下有子文件夹,可是导出的图片和视频依旧保存在“2022-01-02-NONE”文件里(我想让图片和视频直接存在2022-01-02文件下)
2021年5月-2022年2月,我都是使用博主lidashent的照片分类代码,原始代码如下:
# ———————————————— # 版权声明:本文为CSDN博主「lidashent」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 # 原文链接:https://blog.csdn.net/lidashent/article/details/113919375 # ———————————————— import os,shutil import time import datetime allFileNum = 0 myfile=[] mydir=[] movie_file_format=['avi','mpeg','mp4','mov','ProRes','DNxHR','mfx','mkv','wmv','flv','rmvb','webm','asf'] text_file_format=['DOC','PDF','HTML','TXT','HTL','DOCX'] img_file_format=['bmp','jpg','jpeg','png','tif','gif','pcx','tga','exif','fpx','svg','psd', 'cdr','pcd','dxf','ufo','eps','ai','raw','WMF','webp','avif','hdri','flic','emf','ico'] zip_file_format=['rar' ,'zip','7z','CAB','ARJ','LZH','TAR','GZ','ACE','UUE','BZ2','JAR','ISO','MPQ'] music_file_format=['PCM','WAV','AIFF','MP3','AAC','OGG','WMA','FLAC','ALAC','WMA'] this_folder=input("原始路径:").replace("\\",'/') # this_folder='D:\03照片导出' those_folder=input("目标路径:").replace("\\",'/') # those_folder='D:\04照片整理' def printPath(level, path): global allFileNum ''''' 打印一个目录下的所有文件夹和文件 ''' # 所有文件夹,第一个字段是次目录的级别 dirList = [] # 所有文件 fileList = [] # 返回一个列表,其中包含在目录条目的名称(google翻译) files = os.listdir(path) # 先添加目录级别 dirList.append(str(level)) for f in files: if (os.path.isdir(path + '/' + f)): # 排除隐藏文件夹。因为隐藏文件夹过多 if (f[0] == '.'): pass else: # 添加非隐藏文件夹 dirList.append(f) mydir.append(path + '/' + f) if (os.path.isfile(path + '/' + f)): # 添加文件 fileList.append(f) myfile.append(path + '/' + f) # 当一个标志使用,文件夹列表第一个级别不打印 i_dl = 0 for dl in dirList: if (i_dl == 0): i_dl = i_dl + 1 else: # print("得到的文件夹",'-' * (int(dirList[0])), dl) # 打印目录下的所有文件夹和文件,目录级别+1 printPath((int(dirList[0]) + 1), path + '/' + dl) for fl in fileList: # print("得到的文件路径",'-' * (int(dirList[0])), fl) # 随便计算一下有多少个文件 allFileNum = allFileNum + 1 #文件处理 def judge_file(oldPath,location): def TimeStampToTime(timestamp): timeStruct = time.localtime(timestamp) return time.strftime('%Y-%m-%d %H:%M:%S', timeStruct) def get_file_format(file_path): file_name=file_path.split("/")[-1] if file_name.find(".")>0: file_format=file_name.split('.')[-1] if file_format.lower() in movie_file_format or file_format.upper() in movie_file_format: return "视频" elif file_format.lower() in text_file_format or file_format.upper() in text_file_format: return "文本" elif file_format.lower() in img_file_format or file_format.upper() in img_file_format: return "图片" elif file_format.lower() in music_file_format or file_format.upper() in music_file_format: return "音频" elif file_format.lower() in zip_file_format or file_format.upper() in zip_file_format: return "压缩" else: return "其他" else: return "文本" def move_file(new_dir): old_file_name = oldPath.split("/")[-1] # 将文件移动到新文件夹 shutil.move(oldPath, new_dir + '/' + old_file_name) # a->b print("-"*50+"已完成:%.2f" % ((location + 1) / allFileNum*100)) # ImageDate = datetime.datetime.strftime(time.ctime(os.stat(imgPath).st_mtime), "%Y-%m-%d %H:%M:%S") a = os.stat(oldPath).st_mtime #得到文件创建时间,判断文件夹是否存在 creat_time=TimeStampToTime(a)[:-9] print(creat_time) #str 2021-01-10 10:05:31 folder_format=get_file_format(oldPath) new_dir="%s/%s/%s"%(those_folder,creat_time,folder_format) #不存在文件夹则创建文件夹 if not os.path.exists(new_dir): os.makedirs(new_dir) move_file(new_dir) #如果存在就判断是否是重复文件 else : if oldPath.split("/")[-1] in os.listdir(new_dir): print("重复文件,略过") pass else: move_file(new_dir) def do_all(): for i in myfile: judge_file(i,myfile.index(i)) printPath(1, this_folder) do_all() input()
由于本人并不需要将每天拍摄的照片和视频分别保存在“图片”“视频”文件内,因此,将部分涉及格式的内容进行了注释处理。
import os,shutil import time import datetime allFileNum = 0 myfile=[] # mydir=[] # movie_file_format=['avi','mpeg','mp4','mov','ProRes','DNxHR','mfx','mkv','wmv','flv','rmvb','webm','asf'] # text_file_format=['DOC','PDF','HTML','TXT','HTL','DOCX'] # img_file_format=['bmp','jpg','jpeg','png','tif','gif','pcx','tga','exif','fpx','svg','psd', # 'cdr','pcd','dxf','ufo','eps','ai','raw','WMF','webp','avif','hdri','flic','emf','ico'] # zip_file_format=['rar' ,'zip','7z','CAB','ARJ','LZH','TAR','GZ','ACE','UUE','BZ2','JAR','ISO','MPQ'] # music_file_format=['PCM','WAV','AIFF','MP3','AAC','OGG','WMA','FLAC','ALAC','WMA'] this_folder= 'D:\\03照片导出' # this_folder=input("原始路径:").replace("\\",'/') those_folder='D:\\04照片整理' # those_folder=input("目标路径:").replace("\\",'/') def printPath(level, path): global allFileNum ''''' 打印一个目录下的所有文件夹和文件 ''' # 所有文件夹,第一个字段是次目录的级别 dirList = [] # 所有文件 fileList = [] # 返回一个列表,其中包含在目录条目的名称(google翻译) files = os.listdir(path) # 先添加目录级别 dirList.append(str(level)) for f in files: if (os.path.isdir(path + '/' + f)): # 排除隐藏文件夹。因为隐藏文件夹过多 if (f[0] == '.'): pass else: # 添加非隐藏文件夹 dirList.append(f) # mydir.append(path + '/' + f) if (os.path.isfile(path + '/' + f)): # 添加文件 fileList.append(f) myfile.append(path + '/' + f) # 当一个标志使用,文件夹列表第一个级别不打印 i_dl = 0 for dl in dirList: if (i_dl == 0): i_dl = i_dl + 1 else: # print("得到的文件夹",'-' * (int(dirList[-1])), dl) # 打印目录下的所有文件夹和文件,目录级别+1 printPath((int(dirList[0]) + 1), path + '/' + dl) for fl in fileList: # print("得到的文件路径",'-' * (int(dirList[-1])), fl) # 随便计算一下有多少个文件 allFileNum = allFileNum + 1 def judge_file(oldPath,location): def TimeStampToTime(timestamp): timeStruct = time.localtime(timestamp) return time.strftime('%Y-%m-%d %H:%M:%S', timeStruct) def get_file_format(file_path): file_name=file_path.split("/")[-1] # if file_name.find(".")>0: # file_format=file_name.split('.')[-1] # if file_format.lower() in movie_file_format or file_format.upper() in movie_file_format: # return "视频" # # elif file_format.lower() in text_file_format or file_format.upper() in text_file_format: # # return "文本" # elif file_format.lower() in img_file_format or file_format.upper() in img_file_format: # return "图片" # elif file_format.lower() in music_file_format or file_format.upper() in music_file_format: # return "音频" # elif file_format.lower() in zip_file_format or file_format.upper() in zip_file_format: # return "压缩" # else: # return "其他" # else: # return "文本" def move_file(new_dir): old_file_name = oldPath.split("/")[-1] # 将文件移动到新文件夹 shutil.move(oldPath, new_dir + '/' + old_file_name) # a->b print("-"*50+"已完成:%.2f" % ((location + 1) / allFileNum*100)) # ImageDate = datetime.datetime.strftime(time.ctime(os.stat(imgPath).st_mtime), "%Y-%m-%d %H:%M:%S") a = os.stat(oldPath).st_mtime #得到文件创建时间,判断文件夹是否存在 creat_time=TimeStampToTime(a)[:-9] print(creat_time) #str 2021-01-10 10:05:31 folder_format=get_file_format(oldPath) new_dir="%s/%s/%s"%(those_folder,creat_time,folder_format) #不存在文件夹则创建文件夹 if not os.path.exists(new_dir): os.makedirs(new_dir) move_file(new_dir) #如果存在就判断是否是重复文件 else : if oldPath.split("/")[-1] in os.listdir(new_dir): print("重复文件,略过") pass else: move_file(new_dir) def do_all(): for i in myfile: judge_file(i,myfile.index(i)) printPath(1, this_folder) do_all() input() # ———————————————— # 版权声明:本文为CSDN博主「lidashent」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 # 原文链接:https://blog.csdn.net/lidashent/article/details/113919375
虽然将不需要的内容注释了,但保存时,我发现每天的图片和视频一起保存在‘’日期下的none文件里‘’,而不是直接存在‘’日期‘下面,整理时,我要再次点开none文件,将里面的图片和视频拖到到2022-02-22下,然后再次进行手动分类,整理日期如果很多,这样的重复拖动就显得无聊。
(图片视频在none文件下)
当然,这个代码已经帮助我解决了按日期快速整理照片的需求,提高了时间效率。只是最后我还要通过人工观测将一整天的照片进行分组(难以程序化处理),所以希望把照片视频直接放在日期下,不要有none文件的存在来增加额外工作量。
在马先生的指导下,3月2日,我开始尝试对博主lidashent的照片分类代码进行解读,将每一段不理解的代码放到百度里搜索可能的含义,并进行注释。在从上到下的注释后,终于在第95行获得了想要的结果。(由于这里解决了,97行后面的代码注释就没有详细解读,以后有机会再研究)
原来日期下有none文件的原因是“新列表定义了三级文件夹( new_dir="%s/%s%s" 路径-日期-格式),如果将新列表定义两级( new_dir="%s/%s"路径-日期),就可以实现照片视频统一放在日期目录下的结果。
具体代码
import os,shutil import time import datetime allFileNum = 0# 所有文件数量从0开始 myfile=[]# 我的文件 mydir=[]# 我的列表 movie_file_format=['avi','mpeg','mp4','mov','ProRes','DNxHR','mfx','mkv','wmv','flv','rmvb','webm','asf']# 视频格式 text_file_format=['DOC','PDF','HTML','TXT','HTL','DOCX']# 文本格式 img_file_format=['bmp','jpg','jpeg','png','tif','gif','pcx','tga','exif','fpx','svg','psd', 'cdr','pcd','dxf','ufo','eps','ai','raw','WMF','webp','avif','hdri','flic','emf','ico']# 图片格式 zip_file_format=['rar' ,'zip','7z','CAB','ARJ','LZH','TAR','GZ','ACE','UUE','BZ2','JAR','ISO','MPQ']# 压缩格式 music_file_format=['PCM','WAV','AIFF','MP3','AAC','OGG','WMA','FLAC','ALAC','WMA']# 音乐格式 this_folder= 'D:\\03照片导出' # 整理前的照片所在文件夹,原始路径: # this_folder=input("原始路径:").replace("\\",'/') those_folder='D:\\04照片整理'# 整理后的照片所在文件夹(原照片删除),目标路径: # those_folder=input("目标路径:").replace("\\",'/') def printPath(level, path):# 定义输出路径(层级,路径字符串) global allFileNum # 返回allFileNum的全局变量 ''''' 打印一个目录下的所有文件夹和文件 ''' # 所有文件夹,第一个字段是次目录的级别 dirList = [] # 目录清单 # 所有文件 fileList = [] # 返回一个列表,其中包含在目录条目的名称(google翻译) files = os.listdir(path) # 先添加目录级别 dirList.append(str(level)) for f in files: if (os.path.isdir(path + '/' + f)): # os.path.isdir()用于判断对象是否为一个目录 if (f[0] == '.'):# 排除隐藏文件夹。因为隐藏文件夹过多 pass else: # 添加非隐藏文件夹 dirList.append(f) # mydir.append(path + '/' + f) if (os.path.isfile(path + '/' + f)): # 添加文件 fileList.append(f) myfile.append(path + '/' + f) # 当一个标志使用,文件夹列表第一个级别不打印 i_dl = 0 for dl in dirList: if (i_dl == 0): i_dl = i_dl + 1 else: # print("得到的文件夹",'-' * (int(dirList[-1])), dl) # 打印目录下的所有文件夹和文件,目录级别+1 printPath((int(dirList[0])+1), path + '/' + dl) for fl in fileList: # print("得到的文件路径",'-' * (int(dirList[-1])), fl) # 随便计算一下有多少个文件 allFileNum = allFileNum + 1 def judge_file(oldPath,location): # 定义判断文件(老文件,位置) def TimeStampToTime(timestamp):# 定义时间转戳时间(时间戳) timeStruct = time.localtime(timestamp)#时间结构体等于,格式化时间戳为本地的时间(时间戳) return time.strftime('%Y-%m-%d %H:%M:%S', timeStruct)#返回本地时间戳(结构累心,时间结构体) def get_file_format(file_path): # 定义获取后的文件格式(文件路径) file_name=file_path.split("/")[-1] #文件名称等于 文件路径 的最后一段 split("/")[-1] 以‘/ ’为分割f符,保留最后一段 # if file_name.find(".")>0: # file_format=file_name.split('.')[-1] #文件名称等于 文件路径 的最后一段 # if file_format.lower() in movie_file_format or file_format.upper() in movie_file_format: # return "视频" # # elif file_format.lower() in text_file_format or file_format.upper() in text_file_format: # # return "文本" # elif file_format.lower() in img_file_format or file_format.upper() in img_file_format: # return "图片" # elif file_format.lower() in music_file_format or file_format.upper() in music_file_format: # return "音频" # elif file_format.lower() in zip_file_format or file_format.upper() in zip_file_format: # return "压缩" # else: # return "其他" # else: # return "文本" def move_file(new_dir):#定义转移文件 新的列表 old_file_name = oldPath.split("/")[-1]#老文件名等于老路径的最后一段 # 将文件移动到新文件夹 shutil.move(oldPath, new_dir + '/' + old_file_name) # a->b print("-"*50+"已完成:%.2f" % ((location + 1) / allFileNum*100)) # ImageDate = datetime.datetime.strftime(time.ctime(os.stat(imgPath).st_mtime), "%Y-%m-%d %H:%M:%S") a = os.stat(oldPath).st_mtime # 文件时间戳 os.stat(老路径文件).st_mtime #得到文件创建时间,判断文件夹是否存在 creat_time=TimeStampToTime(a)[:-9] # 创造时间戳 print(creat_time) #打印创造的时间 str 2021-01-10 10:05:31 folder_format=get_file_format(oldPath) # 新列表展示为三段式结构——整理后的路径(一级文件夹),创造的时间(二级文件夹),文件格式(图片 视频等 三级文件夹) # new_dir="%s/%s/%s"%(those_folder,creat_time,folder_format) # 阿夏需要两级文件夹(整理后的路径(一级文件夹),创造的时间(二级文件夹)里面装了混合的照片和视频。手动整理) new_dir="%s/%s"%(those_folder,creat_time) #不存在文件夹则创建文件夹 if not os.path.exists(new_dir): os.makedirs(new_dir) move_file(new_dir) #如果存在就判断是否是重复文件 else : if oldPath.split("/")[-1] in os.listdir(new_dir): print("重复文件,略过") pass else: move_file(new_dir) def do_all(): for i in myfile: judge_file(i,myfile.index(i)) printPath(1, this_folder) do_all() input() # ———————————————— # 版权声明:本文为CSDN博主「lidashent」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 # 原文链接:https://blog.csdn.net/lidashent/article/details/113919375
鸣谢:
感谢CSDN博主「lidashent」的原创文章为我的班级工作(照片整理)带来的便利,这也提醒我需要真正读懂代码,才能学以致用,自行修改实现自己的需求。