这几年拍了很多照片,有60G数据,很乱,想要按照年分文件夹管理保存起来存储到百度云盘去。
python
import os
import shutil
from PIL import Image
from PIL.ExifTags import TAGS
import re
import exifread
import datetime
import time
import pillow_heif
import sys
import zipfile
# 注册 HEIF 插件
pillow_heif.register_heif_opener()
# 源目录和目标目录(分别是桌面的两个文件夹,imagessource里面放了原始图片数据,imagesprocess是处理后的结果)
source_dir = os.path.join(os.path.expanduser('~'), 'Desktop', 'imagessource')
target_dir = os.path.join(os.path.expanduser('~'), 'Desktop', 'imagesprocess')
# 创建目标目录
if not os.path.exists(target_dir):
os.makedirs(target_dir)
# 创建截屏文件夹
screenshot_dir = os.path.join(target_dir, 'screenshots')
if not os.path.exists(screenshot_dir):
os.makedirs(screenshot_dir)
def extract_year_from_filename(filename):
# 定义匹配年份的正则表达式模式
pattern = r'\d{4}'
# 使用正则表达式在文件名中查找匹配项
match = re.search(pattern, filename)
if match:
# 如果找到匹配项,返回匹配的年份
return match.group()
return None
def get_heic_type_file_date(image_path):
try:
# 打开图片
with Image.open(image_path) as image:
# 获取 EXIF 数据
exif_data = image.getexif()
if exif_data is not None:
# 遍历 EXIF 数据
for tag, value in exif_data.items():
tag_name = TAGS.get(tag)
if tag_name == 'DateTime':
return value[:4]
except Exception as e:
print(f"Error getting EXIF data: {e}")
return None
def get_creation_date(filename):
if filename.endswith(('.heic')):
return get_heic_type_file_date(filename)
try:
fd = open(filename, 'rb')
except:
print("Cannot open: ", filename)
raise ReadFailException
try:
data = exifread.process_file(fd)
if data:
try:
t = data['EXIF DateTimeOriginal']
return str(t).replace(":", ".")[:4]
except:
print("No exif: ", filename)
pass
finally:
fd.close()
state = os.stat(filename)
print("get state", filename)
fileNameYear = extract_year_from_filename(filename);
if fileNameYear:
return str(fileNameYear)
return time.strftime("%Y", time.localtime(state[-2]))
def is_screenshot(file_name):
# 简单判断是否为截屏文件,可根据实际情况调整
patterns = [r'screenshot', r'screencapture', r'snap']
for pattern in patterns:
if re.search(pattern, file_name, re.IGNORECASE):
return True
return False
# 遍历源目录,分类处理文件
def processFile():
for root, dirs, files in os.walk(source_dir):
for file in files:
file_path = os.path.join(root, file)
if file.lower().endswith(('.png', '.jpg', '.jpeg','.heic')):
if is_screenshot(file):
shutil.move(file_path, os.path.join(screenshot_dir, file))
else:
year = get_creation_date(file_path)
if year:
year_dir = os.path.join(target_dir, year)
if not os.path.exists(year_dir):
os.makedirs(year_dir)
shutil.move(file_path, os.path.join(year_dir, file))
else:
# 如果无法获取拍摄日期,放到一个单独的文件夹
unknown_dir = os.path.join(target_dir, 'unknown_date')
if not os.path.exists(unknown_dir):
os.makedirs(unknown_dir)
shutil.move(file_path, os.path.join(unknown_dir, file))
def extract_first_heic(livp_path):
"""
从.livp文件中提取第一张HEIC图片
参数:
livp_path (str): .livp文件的路径
output_dir (str): 输出目录(默认当前目录)
返回:
str: 提取的HEIC文件路径
异常:
ValueError: 如果文件无效或无HEIC文件
"""
# 检查文件是否存在
if not os.path.isfile(livp_path):
raise FileNotFoundError(f"文件 '{livp_path}' 不存在")
processSucess = False
try:
with zipfile.ZipFile(livp_path, 'r') as zf:
# 筛选HEIC文件(不区分大小写)
heic_files = [
f for f in zf.namelist()
if os.path.splitext(f)[1].lower() == '.heic'
]
if not heic_files:
return
# 按文件名排序(默认升序)
heic_files.sort()
first_heic = heic_files[0]
# 提取文件
livp_dir = os.path.dirname(livp_path)
zf.extract(first_heic, livp_dir)
extracted_path = os.path.join(livp_dir, first_heic)
# 获取livp_path文件名
livp_filename = os.path.basename(livp_path)
print(f"LIVP文件名: {livp_filename}")
# 修改文件名为 aaa.jpg
new_path = os.path.join(livp_dir, os.path.basename(livp_path) + first_heic)
if not os.path.exists(new_path):
os.rename(extracted_path, new_path)
# 删除 extracted_path 文件
if os.path.isfile(extracted_path):
os.remove(extracted_path)
extracted_path = new_path
processSucess = True
# 返回完整路径
return os.path.abspath(extracted_path)
except zipfile.BadZipFile:
raise ValueError("无效的LIVP文件(非ZIP格式)")
finally:
# 删除原始文件
if os.path.isfile(livp_path) and processSucess:
os.remove(livp_path)
# 格式转换文件 :python 提取 .livp 里面的第一张 heic 图片,并且删除原始 .livp 文件
def livp_to_jpgProcess():
for root, dirs, files in os.walk(source_dir):
for file in files:
file_path = os.path.join(root, file)
if file.lower().endswith(('.livp')):
extract_first_heic(file_path)
# 第一步 提取 .livp 里面的第一张 heic 图片
# livp_to_jpgProcess()
# 第二步处理数据
processFile()