Python 办公效率化学习(自学) 二.照片信息的读取与分类(适用于exif信息存在的照片整理)

目录

照片信息的读取与分类:

Day1

 一.步骤解析:

二.具体操作:

(1)获取待整理照片文件列表

Day1  阶段总结 

Day2 

(2)获取照片拍摄日期

(3)创建对应日期文件夹

(4) 将照片移动到对应文件夹

Day2阶段总结

三.总代码

实操遇见的问题:

读取图片的exif信息得到空的字典

知识点

Exif相关知识点(便于理解) 


照片信息的读取与分类:

Day1

 一.步骤解析:

1.获取待整理照片文件列表
2.逐个获取照片拍摄时间
3.如果对应年月的文件夹不存在,则创建对应文件夹
4.移动照片到对应年月的文件夹中

二.具体操作:

(1)获取待整理照片文件列表

在运行各种跟文件打交道的程序时,比较常出现的错误是“文件未找到错误(FileNotFoundError)”。

出现这种问题,可能是因为文件本身就不存在,但也有可能是由于对各种路径的概念不熟悉而导致的代码错误。

所以在着手解决今天的问题之前,我们需要先继续深入学习路径相关的概念
 

1.工作目录:每一个Python程序运行的时候,都有一个工作目录(Working Directory)显示当前的Python程序是运行在哪一个路径之下。

 2.绝对路径:Windows系统中的路径是以盘符+冒号开始,在macOS系统中是以正斜线( / )开始。
其实这种以盘符+冒号或正斜线( / )开始的路径又叫绝对路径(Absolute Path)。

 3.相对路径:直接以文件或文件夹的名称开头,相对于工作目录的路径位置。

比如工作目录为:/Users/yequ                              

相对路径为: aha/答辩.pptx                                        

对应的绝对路径就是:
/Users/yequ/aha/答辩.pptx

如果相对路径为:自拍.jpg

对应的绝对路径就是:
/Users/yequ/自拍.jpg

注意 :脱离了工作目录,单独存在的相对路径没有意义。

而同时有了相对路径和工作目录,就可以定位到具体位置的绝对路径。

在程序中,使用相对路径可以避免频繁地输入完整文件路径,起到简化代码的作用。

使用os.getcwd()函数可以用来获取当前程序的工作目录。

要修改程序运行时的工作目录,需要使用os.chdir()函数。

将新的路径作为参数传入该函数,即可将工作目录修改到目标路径。

Day1  阶段总结 

# 导入os模块
import os

# 输出当前工作目录
print(os.getcwd())

# TODO 修改当前工作目录到/Volumes/backup
os.chdir("/Volumes/backup")

# TODO 再次输出当前工作目录以确认修改成功
print(os.getcwd())

Day2 

(2)获取照片拍摄日期

正常情况下,每一张用手机或者相机拍照片都会带有EXIF(Exchangeable image file format)信息。

而这个EXIF信息中就有每张照片拍摄的时间。要通过Python去读取照片的EXIF信息,可以使用ezexif这个模块。

ezexif不是一个内置模块,所以在使用前要先通过代码 pip install ezexif 进行安装。

如果在自己电脑上安装不上或安装缓慢,可在命令后添加
pip install ezexif -i https://pypi.tuna.tsinghua.edu.cn/simple/
进行加速

安装了ezexif模块后,只需要将照片路径传入ezexif.process_file()函数就可以获得一个包含图片EXIF信息的字典(dict)。

通过这个字典访问“EXIF DateTimeOriginal”属性即可获得照片的拍摄时间。

需要注意的是,每一张照片的路径需要使用前面学过的os.path.join()函数将文件夹相对路径和照片文件名来组合。 

# 导入os模块
import os

# 导入ezexif模块
import ezexif

# 修改当前工作目录到/Volumes/backup
os.chdir('/Volumes/backup')

# 获取待处理照片的相对路径
backupPhotoPath = "照片"

# 使用函数os.listdir()获取所有待处理照片文件列表
photoList = os.listdir(backupPhotoPath)

# 遍历文件列表
for photo in photoList:
    # 使用os.path.join()函数组合得到照片文件路径,并赋值给变量photoPath
    photoPath = os.path.join(backupPhotoPath, photo)
    # 获取exif信息
    exifInfo = ezexif.process_file(photoPath)
    # 获取拍摄时间并输出
    takeTime = exifInfo["EXIF DateTimeOriginal"]
    print(takeTime)

(3)创建对应日期文件夹

1. 分隔字符串

拿到了照片的拍摄时间后,就可以根据拍摄的年份和月份来确定照片要移动到的文件夹路径了。

现在我们来分析一下如何从表示拍摄时间这个字符串中(2015:12:10 21:08:08 )提取出拍摄的年份和月份。

整个字符串由一个空格将拍摄的日期和具体的时间分隔开来。

在拍摄日期的部分中,拍摄的年、月、日又被两个冒号分隔开来。
同样的,拍摄时间也被两个冒号分隔成了时、分、秒三个部分。 

2.创建文件夹

学会了通过分隔字符串来提取拍摄的年、月、日之后,下一步就可以通过格式化字符串的方式,以年份和月份为参数给照片文件夹进行命名了(命名格式:xxxx年xx月)。 

# 遍历文件列表
for photo in photoList:
    # 使用os.path.join()函数组合得到照片文件路径,并赋值给变量photoPath
    photoPath = os.path.join(backupPhotoPath, photo)
    # 获取exif信息
    exifInfo = ezexif.process_file(photoPath)
    # 获取拍摄时间
    takeTime = exifInfo["EXIF DateTimeOriginal"]
    # 通过空格分隔成拍摄日期和拍摄时间
    takeTimeParts = takeTime.split(" ")
    # 分隔后的字符串列表第一个元素就是拍摄日期,赋值给变量photoDate
    photoDate = takeTimeParts[0]
    # 再把拍摄日期通过冒号分隔,分成年、月、日三部分,赋值给变量photoDateParts
    photoDateParts = photoDate.split(":")

    # 利用格式化字符串拼出文件夹名称
    targetFolderName = f"{photoDateParts[0]}年{photoDateParts[1]}月"
    # 使用os.path.join()函数拼出分类文件夹的路径, 并赋值给photoTargetPath变量
    photoTargetPath = os.path.join(backupPhotoPath, targetFolderName)

    # TODO 使用os.path.exists()函数判断当照片分类的文件夹不存在时
    if not os.path.exists(photoTargetPath):
        # TODO 使用os.mkdir()函数创建文件夹
        os.mkdir(photoTargetPath)

(4) 将照片移动到对应文件夹

 运用shutil即可

Day2阶段总结

三.总代码

# 导入os模块
import os

# TODO 导入ezexif模块
import ezexif

# TODO 导入shutil模块
import shutil

# TODO 使用os.chdir()函数修改当前工作目录到/Volumes/yequ
os.chdir("/Volumes/yequ")

# 照片的相对路径
yequPhotoPath = "照片"

# TODO 使用函数os.listdir()获取所有待处理照片文件列表,并赋值给变量photoList
photoList = os.listdir(yequPhotoPath)

# 使用for循环遍历文件列表photoList
for photo in photoList:
    # 使用os.path.join()函数组合得到照片文件路径,并赋值给变量photoPath
    photoPath = os.path.join(yequPhotoPath, photo)
    # TODO 使用函数ezexif.process_file获取exif信息,并赋值给变量exifInfo
    exifInfo = ezexif.process_file(photoPath)
    # TODO 通过访问变量exifInfo的“EXIF DateTimeOriginal”字段获取拍摄时间赋值给变量takeTime
    takeTime = exifInfo["EXIF DateTimeOriginal"]
    # TODO 使用split()函数,通过空格分隔成拍摄日期和拍摄时间,赋值给变量takeTimeParts
    takeTimeParts = takeTime.split(" ")
    # 分隔后的字符串列表第一个元素就是拍摄日期,赋值给变量photoDate
    photoDate = takeTimeParts[0]
    # TODO 再把拍摄日期通过冒号分隔,分成年、月、日三部分,赋值给变量photoDateParts
    photoDateParts = photoDate.split(":")

    # TODO 利用格式化字符串拼出分类文件夹名称xxx年xx月, 并赋值给变量targetFolderName
    targetFolderName = f"{photoDateParts[0]}年{photoDateParts[1]}月"
    # 使用os.path.join()函数拼出分类文件夹的路径, 并赋值给photoTargetPath变量
    photoTargetPath = os.path.join(yequPhotoPath, targetFolderName)

    # 如果目标文件夹不存在,使用os.mkdir()函数创建文件夹
    if not os.path.exists(photoTargetPath):
        os.mkdir(photoTargetPath)

    # 移动到目标文件夹
    shutil.move(photoPath, photoTargetPath)

实操遇见的问题:

读取图片的exif信息得到空的字典

知识点:

1、有的网站不支持显示exif信息

2、剪裁后再建新文件编辑的是没有exif信息的

3、用一些特殊的软件编辑后也有可能抹掉exif信息。

4、ps好图片以后选择高质量保存,然后还选jpg格式,这样不容易丢失exif。

5.必须得是拍摄的原片上传才有exif信息的。

这个包括无损压缩之后的图片。

但是非原图,只要经过过滤过的图片都是没有exif信息的,比如QQ直接发的图片就没有,但是传送的图片就有。

Exif相关知识点(便于理解) :

https://baike.baidu.com/item/Exif/422825?fr=aladdin

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值