问题描述:
某一文件夹下有N个子文件夹,子文件夹内的图片均为3张,且命名方式为xxxA.jpg,xxxB.jpg和xxxC.jpg(xxx为子文件夹名),要求将所有子文件夹内xxxC.jpg图片和xxxB.jpg图片的拍摄时间修改为xxxA.jpg拍摄时间的后续100~500s范围内,且每张图片的创建时间/修改时间均为自己修改后的拍摄时间,xxxC.jpg图片和xxxB.jpg的相机参数/手机参数与xxxA.jpg相同。
使用工具:python
版本:3.7.0
模块:piexif(1.1.3),Pillow(7.2.0),win32,easygui(0.98.2)
import easygui
import time
import os
import random
import piexif
from PIL import Image
from win32file import CreateFile, SetFileTime, GetFileTime, CloseHandle
from win32file import GENERIC_READ, GENERIC_WRITE, OPEN_EXISTING
from pywintypes import Time
pic = easygui.enterbox("文件夹路径:")
def TimeStampToTime(timestamp):
timeStruct = time.localtime(timestamp)
return time.strftime('%d.%m.%Y %H:%M:%S',timeStruct)
def set_file_time(file, rootDir):
# 先传修改时间,再传访问时间
filePath = rootDir + '\\' + file.split('.jpg')[0][:-1] + '\\' + file
filePath1 = rootDir + '\\' + file.split('.jpg')[0][:-1] + '\\' + file.split('.jpg')[0][:-1] + 'B' + '.jpg'
filePath2 = rootDir + '\\' + file.split('.jpg')[0][:-1] + '\\' + file.split('.jpg')[0][:-1] + 'C' + '.jpg'
im0 = Image.open(filePath)
exif_dict0 = piexif.load(im0.info["exif"])
im0.close()
CameraOwnerName = ''
LensModel = ''
Software = ''
# 某些照片的Scenetype不是byte类型,强制变更所有照片的Scenetype为b'\x01',防止部分报错。
Scenetype = b'\x01'
format = "%d.%m.%Y %H:%M:%S"
r1 = random.randint(60, 500)
r2 = random.randint(60, 500)
try:
oldtime = exif_dict0["0th"][306].decode()
set_wai_time(filePath, oldtime)
CameraOwnerName = exif_dict0["0th"][271]
LensModel = exif_dict0["0th"][272]
Software = exif_dict0["0th"][305]
timelist = oldtime.split(' ')
year = timelist[0].split(':')[0]
month = timelist[0].split(':')[1]
day = timelist[0].split(':')[2]
hour = timelist[1].split(':')[0]
minute = timelist[1].split(':')[1]
second = timelist[1].split(':')[2]
pttime = day + '.' + month + '.' + year + ' ' + hour + ':' + minute + ':' + second
cTime_t = int(time.mktime(time.strptime(pttime, format)))
newim1 = time.strftime("%Y:%m:%d %H:%M:%S", time.localtime((cTime_t + r1)))
newim2 = time.strftime("%Y:%m:%d %H:%M:%S", time.localtime((cTime_t + r1 + r2)))
except:
pttime = TimeStampToTime(os.path.getctime(filePath))
cTime_t = int(time.mktime(time.strptime(pttime, format)))
newim1 = time.strftime("%Y:%m:%d %H:%M:%S", time.localtime((cTime_t + r1)))
newim2 = time.strftime("%Y:%m:%d %H:%M:%S", time.localtime((cTime_t + r1 + r2)))
changeDate(filePath1,newim1,CameraOwnerName,LensModel,Software,Scenetype)
changeDate(filePath2, newim2,CameraOwnerName,LensModel,Software,Scenetype)
set_wai_time(filePath1, newim1)
set_wai_time(filePath2, newim2)
def set_wai_time(fName, pttime):
# 先传修改时间,再传访问时间
format ="%Y:%m:%d %H:%M:%S"
offset = 0 # in seconds
# create struct_time object
cTime_t = time.localtime(time.mktime(time.strptime(pttime, format)) + offset)
mTime_t = time.localtime(time.mktime(time.strptime(pttime, format)) + offset)
aTime_t = time.localtime(time.mktime(time.strptime(pttime, format)) + offset)
# change timestamp of file
fh = CreateFile(fName, GENERIC_READ | GENERIC_WRITE, 0, None, OPEN_EXISTING, 0, 0)
createTime, accessTime, modifyTime = GetFileTime(fh)
createTime = Time(time.mktime(cTime_t))
accessTime = Time(time.mktime(aTime_t))
modifyTime = Time(time.mktime(mTime_t))
SetFileTime(fh, createTime, accessTime, modifyTime)
CloseHandle(fh)
#
def changeDate(imgName,takeTime,CameraOwnerName,LensModel,Software,Scenetype):
im = Image.open(imgName)
exif_dict = piexif.load(im.info["exif"])
exif_dict["0th"][306] = takeTime
exif_dict["Exif"][piexif.ExifIFD.DateTimeOriginal] = takeTime
exif_dict["Exif"][piexif.ExifIFD.DateTimeDigitized] = takeTime
exif_dict["0th"][271] = CameraOwnerName
exif_dict["0th"][272] = LensModel
exif_dict["0th"][305] = Software
exif_dict["Exif"][41729] = Scenetype
try:
exif_bytes = piexif.dump(exif_dict)
piexif.insert(exif_bytes, imgName)
except:
print('failed:',imgName)
def bianLi(rootDir):
for root, dirs, files in os.walk(rootDir):
for file in files:
set_file_time(file,rootDir)
print('修改:',file)
break
bianLi(pic)