用python实现整理手机图片小应用

发布时间:2021-07-13 10:34:07 作者:chen
来源:亿速云 阅读:190
# 用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

4. 核心功能实现

4.1 图片读取与元数据提取

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

4.2 按日期分类

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}")

4.3 按地点分类

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

4.4 人脸识别分类

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))

4.5 图片重命名

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}")

4.6 重复图片检测

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

5. 用户界面设计

使用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_()

6. 打包与部署

使用PyInstaller打包为可执行文件:

pip install pyinstaller
pyinstaller --onefile --windowed photo_organizer.py

7. 完整代码示例

完整代码已超过展示篇幅,可以从GitHub仓库获取: https://github.com/example/photo-organizer

8. 总结与展望

本文实现了一个基础的手机图片整理工具,具备以下特点:

  1. 自动按日期/地点/人脸分类
  2. 批量重命名功能
  3. 重复图片检测
  4. 友好的图形界面

未来可扩展方向:

通过这个项目,我们展示了Python在文件处理和图像分析方面的强大能力。希望这个工具能帮助您更好地管理手机照片! “`

推荐阅读:
  1. Sed应用整理
  2. iOS 图片保存手机相册

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

python

上一篇:Python pip自动更新升级失败怎么办

下一篇:NodeJs安装npm包一直失败怎么办

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》