您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# 用Python实现整理手机图片小应用
## 引言
在智能手机普及的今天,我们每天都会拍摄大量照片。这些照片往往杂乱地存储在手机相册中,给查找和管理带来诸多不便。本文将介绍如何使用Python开发一个简单的手机图片整理应用,帮助用户自动分类、重命名和归档照片。
## 目录
1. 需求分析
2. 技术选型
3. 开发环境搭建
4. 核心功能实现
- 4.1 图片读取与元数据提取
- 4.2 按日期分类
- 4.3 按地点分类
- 4.4 人脸识别分类
- 4.5 图片重命名
- 4.6 重复图片检测
5. 用户界面设计
6. 打包与部署
7. 完整代码示例
8. 总结与展望
## 1. 需求分析
一个基础的图片整理应用应具备以下功能:
- 按拍摄日期自动分类
- 支持按地理位置信息分组
- 基本的人脸识别分类能力
- 批量重命名功能
- 重复图片检测
- 简单的用户界面
## 2. 技术选型
为实现上述功能,我们选择以下Python库:
- `Pillow`:图像处理
- `ExifRead`:读取照片元数据
- `face_recognition`:人脸识别
- `Pandas`:数据处理
- `PyQt5`:图形界面
- `imagehash`:重复图片检测
## 3. 开发环境搭建
```bash
# 创建虚拟环境
python -m venv photo_organizer
source photo_organizer/bin/activate # Linux/Mac
photo_organizer\Scripts\activate # Windows
# 安装依赖
pip install pillow exifread face-recognition pandas pyqt5 imagehash
import exifread
from PIL import Image
def get_image_metadata(image_path):
"""提取图片EXIF元数据"""
with open(image_path, 'rb') as f:
tags = exifread.process_file(f)
metadata = {}
if 'EXIF DateTimeOriginal' in tags:
metadata['date'] = str(tags['EXIF DateTimeOriginal'])
if 'GPS GPSLatitude' in tags:
metadata['latitude'] = tags['GPS GPSLatitude']
if 'GPS GPSLongitude' in tags:
metadata['longitude'] = tags['GPS GPSLongitude']
return metadata
import os
import shutil
from datetime import datetime
def organize_by_date(source_dir, target_dir):
"""按拍摄日期分类图片"""
if not os.path.exists(target_dir):
os.makedirs(target_dir)
for filename in os.listdir(source_dir):
if filename.lower().endswith(('.jpg', '.jpeg', '.png')):
filepath = os.path.join(source_dir, filename)
try:
metadata = get_image_metadata(filepath)
date_str = metadata.get('date', 'unknown').split()[0].replace(':', '-')
date_dir = os.path.join(target_dir, date_str)
if not os.path.exists(date_dir):
os.makedirs(date_dir)
shutil.copy2(filepath, os.path.join(date_dir, filename))
except Exception as e:
print(f"Error processing {filename}: {e}")
from geopy.geocoders import Nominatim
def get_location_name(lat, lon):
"""通过经纬度获取地点名称"""
geolocator = Nominatim(user_agent="photo_organizer")
location = geolocator.reverse(f"{lat}, {lon}")
return location.address.split(',')[-3].strip()
def organize_by_location(source_dir, target_dir):
"""按拍摄地点分类图片"""
# 实现类似日期分类的逻辑,使用get_location_name获取地点名称
pass
import face_recognition
import numpy as np
def organize_by_faces(source_dir, target_dir):
"""按人脸特征分类图片"""
known_faces = {}
for filename in os.listdir(source_dir):
if filename.lower().endswith(('.jpg', '.jpeg', '.png')):
image_path = os.path.join(source_dir, filename)
image = face_recognition.load_image_file(image_path)
face_encodings = face_recognition.face_encodings(image)
if len(face_encodings) > 0:
found_match = False
for name, encodings in known_faces.items():
matches = face_recognition.compare_faces(encodings, face_encodings[0])
if True in matches:
# 复制到对应人物的文件夹
person_dir = os.path.join(target_dir, name)
os.makedirs(person_dir, exist_ok=True)
shutil.copy2(image_path, os.path.join(person_dir, filename))
found_match = True
break
if not found_match:
# 新人脸,创建新分类
person_name = f"Person_{len(known_faces)+1}"
known_faces[person_name] = [face_encodings[0]]
person_dir = os.path.join(target_dir, person_name)
os.makedirs(person_dir, exist_ok=True)
shutil.copy2(image_path, os.path.join(person_dir, filename))
def rename_images(source_dir, pattern="IMG_%Y%m%d_%H%M%S"):
"""批量重命名图片"""
for filename in os.listdir(source_dir):
if filename.lower().endswith(('.jpg', '.jpeg', '.png')):
filepath = os.path.join(source_dir, filename)
try:
metadata = get_image_metadata(filepath)
if 'date' in metadata:
dt = datetime.strptime(str(metadata['date']), '%Y:%m:%d %H:%M:%S')
new_name = dt.strftime(pattern) + os.path.splitext(filename)[1]
os.rename(filepath, os.path.join(source_dir, new_name))
except Exception as e:
print(f"Error renaming {filename}: {e}")
from imagehash import average_hash
def find_duplicates(source_dir):
"""查找重复图片"""
hashes = {}
duplicates = []
for filename in os.listdir(source_dir):
if filename.lower().endswith(('.jpg', '.jpeg', '.png')):
filepath = os.path.join(source_dir, filename)
try:
with Image.open(filepath) as img:
h = average_hash(img)
if h in hashes:
duplicates.append((filename, hashes[h]))
else:
hashes[h] = filename
except Exception as e:
print(f"Error processing {filename}: {e}")
return duplicates
使用PyQt5创建简单界面:
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget,
QVBoxLayout, QPushButton, QFileDialog,
QLabel, QProgressBar)
class PhotoOrganizerApp(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("手机图片整理工具")
self.setGeometry(100, 100, 400, 300)
self.initUI()
def initUI(self):
central_widget = QWidget()
self.setCentralWidget(central_widget)
layout = QVBoxLayout()
self.source_label = QLabel("未选择源文件夹")
layout.addWidget(self.source_label)
self.target_label = QLabel("未选择目标文件夹")
layout.addWidget(self.target_label)
self.progress = QProgressBar()
layout.addWidget(self.progress)
btn_select_source = QPushButton("选择源文件夹")
btn_select_source.clicked.connect(self.select_source)
layout.addWidget(btn_select_source)
btn_select_target = QPushButton("选择目标文件夹")
btn_select_target.clicked.connect(self.select_target)
layout.addWidget(btn_select_target)
btn_organize_date = QPushButton("按日期整理")
btn_organize_date.clicked.connect(self.organize_by_date)
layout.addWidget(btn_organize_date)
btn_organize_faces = QPushButton("按人脸整理")
btn_organize_faces.clicked.connect(self.organize_by_faces)
layout.addWidget(btn_organize_faces)
central_widget.setLayout(layout)
def select_source(self):
folder = QFileDialog.getExistingDirectory(self, "选择源文件夹")
if folder:
self.source_dir = folder
self.source_label.setText(f"源文件夹: {folder}")
def select_target(self):
folder = QFileDialog.getExistingDirectory(self, "选择目标文件夹")
if folder:
self.target_dir = folder
self.target_label.setText(f"目标文件夹: {folder}")
def organize_by_date(self):
if hasattr(self, 'source_dir') and hasattr(self, 'target_dir'):
organize_by_date(self.source_dir, self.target_dir)
def organize_by_faces(self):
if hasattr(self, 'source_dir') and hasattr(self, 'target_dir'):
organize_by_faces(self.source_dir, self.target_dir)
if __name__ == "__main__":
app = QApplication([])
window = PhotoOrganizerApp()
window.show()
app.exec_()
使用PyInstaller打包为可执行文件:
pip install pyinstaller
pyinstaller --onefile --windowed photo_organizer.py
完整代码已超过展示篇幅,可以从GitHub仓库获取: https://github.com/example/photo-organizer
本文实现了一个基础的手机图片整理工具,具备以下特点:
未来可扩展方向:
通过这个项目,我们展示了Python在文件处理和图像分析方面的强大能力。希望这个工具能帮助您更好地管理手机照片! “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。