背景需求
作为幼儿园老师,每天都会拍摄大量的一日生活照片,于是手机经常提示“内存不足”。2020年之前,阿夏采用的方法是这样的:
1.QQ-我的文件助手-导出手机相册
2.新建一个个文件夹,根据日期,手动拖拽分类
3.操作烦恼——手动整理照片效率太低
通常是一个月整理一次手机照片。需要一次性新建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」的原创文章为我的班级工作(照片整理)带来的便利,这也提醒我需要真正读懂代码,才能学以致用,自行修改实现自己的需求。
来源:https://blog.csdn.net/reasonsummer/article/details/122583051
本站部分图文来源于网络,如有侵权请联系删除。