diff --git a/SnapForge/__pycache__/logic.cpython-312.pyc b/SnapForge/__pycache__/logic.cpython-312.pyc index 885a10c..fe930d5 100644 Binary files a/SnapForge/__pycache__/logic.cpython-312.pyc and b/SnapForge/__pycache__/logic.cpython-312.pyc differ diff --git a/SnapForge/__pycache__/ui.cpython-312.pyc b/SnapForge/__pycache__/ui.cpython-312.pyc index 3de57e2..cda5284 100644 Binary files a/SnapForge/__pycache__/ui.cpython-312.pyc and b/SnapForge/__pycache__/ui.cpython-312.pyc differ diff --git a/SnapForge/logic.py b/SnapForge/logic.py index 6b4226c..52ebff6 100644 --- a/SnapForge/logic.py +++ b/SnapForge/logic.py @@ -8,51 +8,57 @@ # 初始化日志记录 logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') +class ImageProcessor: + def batch_process(self, directory, prefix=None, start_number=1, extension=".jpg", convert_format=None, quality=None, progress_callback=None): + extension = extension.lower() + count = start_number + total_files = 0 + processed_files = 0 -def batch_process(directory, prefix=None, start_number=1, extension=".jpg", convert_format=None, quality=None, - progress_callback=None): - extension = extension.lower() - count = start_number - total_files = 0 # 初始化 total_files 为 0 - processed_files = 0 + files = os.listdir(directory) # 提前获取文件列表 + for filename in files: + if filename.lower().endswith(extension): + total_files += 1 # 更新 total_files - # 每次循环开始前获取文件列表 - for filename in os.listdir(directory): - if filename.lower().endswith(extension): - total_files += 1 # 更新 total_files + src = os.path.join(directory, filename) - src = os.path.join(directory, filename) + # 设置新的文件扩展名 + new_extension = convert_format.lower() if convert_format else extension + if not new_extension.startswith("."): + new_extension = f".{new_extension}" - if prefix: - valid_filename = re.sub(r'[\\/*?:"<>|]', '_', f"{prefix}_{count}") - unique_filename = valid_filename + "_" + str(uuid.uuid4()) - new_extension = f".{convert_format.lower()}" if convert_format else extension - dst = os.path.join(directory, f"{unique_filename}{new_extension}") - - while os.path.exists(dst): - count += 1 + if prefix: + valid_filename = re.sub(r'[\\/*?:"<>|]', '_', f"{prefix}_{count}") + unique_filename = valid_filename + "_" + str(uuid.uuid4()) dst = os.path.join(directory, f"{unique_filename}{new_extension}") - else: - dst = src - - try: - if convert_format: - with Image.open(src) as img: - if new_extension == ".jpg" and img.mode in ("RGBA", "LA"): - img = img.convert("RGB") - img.save(dst, format=convert_format.upper(), quality=quality or 95) # 提供默认质量值 - os.remove(src) + + # 确保目标文件名唯一 + while os.path.exists(dst): + count += 1 + valid_filename = re.sub(r'[\\/*?:"<>|]', '_', f"{prefix}_{count}") + unique_filename = valid_filename + "_" + str(uuid.uuid4()) + dst = os.path.join(directory, f"{unique_filename}{new_extension}") else: - os.rename(src, dst) - except Exception as e: - logging.error(f"处理文件 {filename} 时出错: {e}") - continue - - count += 1 - processed_files += 1 - # 在这里调用 progress_callback,而不是在循环中 - if progress_callback: - progress = int((processed_files / total_files) * 100) - progress_callback(progress) - - return count - start_number \ No newline at end of file + dst = src + + try: + if convert_format: + with Image.open(src) as img: + if new_extension == ".jpg" and img.mode in ("RGBA", "LA"): + img = img.convert("RGB") + img.save(dst, format=convert_format.upper(), quality=quality or 95) # 提供默认质量值 + os.remove(src) + else: + os.rename(src, dst) + except (PermissionError, FileNotFoundError) as e: + logging.error(f"处理文件 {filename} 时发生错误: {e}") + continue + + count += 1 + processed_files += 1 + # 在这里调用 progress_callback + if progress_callback: + progress = int((processed_files / total_files) * 100) + progress_callback(progress) + + return count - start_number diff --git a/SnapForge/ui.py b/SnapForge/ui.py index f9b6324..4cebda4 100644 --- a/SnapForge/ui.py +++ b/SnapForge/ui.py @@ -2,10 +2,10 @@ import os import sys from PyQt6.QtGui import QIcon -from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel, QLineEdit, QPushButton, +from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QLabel, QLineEdit, QPushButton, QFileDialog, QMessageBox, QCheckBox, QProgressBar, QGridLayout) from PyQt6.QtCore import QThread, pyqtSignal -from logic import batch_process # 从 logic.py 导入处理函数 +from logic import ImageProcessor # 从 logic.py 导入 ImageProcessor 类 class WorkerThread(QThread): progress_updated = pyqtSignal(int) @@ -20,17 +20,18 @@ def __init__(self, directory, prefix, start_number, extension, convert_format, c self.extension = extension self.convert_format = convert_format self.compress_quality = compress_quality + self.processor = ImageProcessor() # 实例化 ImageProcessor def run(self): try: - processed_count = batch_process( + processed_count = self.processor.batch_process( self.directory, self.prefix, self.start_number, self.extension, self.convert_format, self.compress_quality, - self.progress_updated + self.update_progress ) self.finished.emit(processed_count) except Exception as e: @@ -38,6 +39,9 @@ def run(self): finally: self.finished.emit(0) + def update_progress(self, progress): + self.progress_updated.emit(progress) + class BatchRenameApp(QMainWindow): def __init__(self): super().__init__()