Skip to content

Commit

Permalink
3.2.3
Browse files Browse the repository at this point in the history
  • Loading branch information
riceshowerX committed Aug 27, 2024
1 parent 036f99c commit 1557667
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 62 deletions.
Binary file modified SnapForge/__pycache__/logic.cpython-312.pyc
Binary file not shown.
Binary file modified SnapForge/__pycache__/ui.cpython-312.pyc
Binary file not shown.
79 changes: 27 additions & 52 deletions SnapForge/logic.py
Original file line number Diff line number Diff line change
@@ -1,76 +1,51 @@
import os
import re
import uuid
from PIL import Image


def batch_process(directory, prefix=None, start_number=1, extension=".jpg", convert_format=None, quality=None,
progress_callback=None):
"""
批量处理图像文件,包括重命名、格式转换和质量压缩。
Args:
directory (str): 要处理的图像文件所在的目录。
prefix (str, optional): 新文件名的前缀。默认为 None,表示不重命名。
start_number (int, optional): 新文件名的起始编号。默认为 1。
extension (str, optional): 要处理的文件扩展名。默认为 ".jpg"。
convert_format (str, optional): 转换后的文件格式,例如 ".png"。默认为 None,表示不转换格式。
quality (int, optional): 保存图像的质量,适用于 JPEG 格式。默认为 None,表示使用默认质量。
progress_callback (function, optional): 进度回调函数,接受一个表示进度的整数参数 (0-100)。
Returns:
int: 处理的文件数量。
"""

extension = extension.lower()
count = start_number
total_files = sum(1 for filename in os.listdir(directory) if filename.lower().endswith(extension))
processed_files = 0

if total_files == 0:
return 0 # 如果没有文件可处理,直接返回

for filename in os.listdir(directory):
if filename.lower().endswith(extension):
src = os.path.join(directory, filename)

if prefix:
# 验证文件名 - 使用正则表达式替换非法字符
valid_filename = re.sub(r'[\\/*?:"<>|]', '_', f"{prefix}_{count}")

unique_filename = valid_filename + "_" + str(uuid.uuid4())
new_extension = convert_format.lower() if convert_format else extension
if not new_extension.startswith("."):
new_extension = f".{new_extension}"

dst = os.path.join(directory, f"{valid_filename}{new_extension}")

while os.path.exists(dst):
count += 1
# 确保在循环中也使用验证后的文件名
valid_filename = re.sub(r'[\\/*?:"<>|]', '_', f"{prefix}_{count}")
dst = os.path.join(directory, f"{valid_filename}{new_extension}")

# 处理图片格式转换和质量压缩
if convert_format or quality is not None:
try:
with Image.open(src) as img:
if convert_format:
if new_extension == ".jpg" and img.mode in ("RGBA", "LA"):
img = img.convert("RGB")
if quality is not None:
img.save(dst, quality=quality)
else:
img.save(dst)
except Exception as e:
print(f"处理文件 {filename} 时出错: {e}")
continue # 跳过出错的文件

dst = os.path.join(directory, f"{unique_filename}{new_extension}")
else:
if prefix: # 仅在需要重命名时才移动文件
try:
os.rename(src, dst)
except Exception as e:
print(f"重命名文件 {filename} 时出错: {e}")
continue # 跳过出错的文件
dst = src # 如果不重命名,则目标路径和源路径相同

# 删除源文件 (仅在需要重命名且文件已成功处理后)
if prefix and os.path.exists(dst):
# 处理图片格式转换和质量压缩
try:
with Image.open(src) as img:
if convert_format:
if new_extension == ".jpg" and img.mode in ("RGBA", "LA"):
img = img.convert("RGB")
img.save(dst, format=convert_format[1:], quality=quality)
elif quality is not None:
img.save(dst, quality=quality)
else:
if prefix:
os.rename(src, dst)
except Exception as e:
print(f"处理文件 {filename} 时出错: {e}")
continue

# 删除源文件 (如果已成功转换或重命名)
if os.path.exists(dst) and dst != src:
try:
os.remove(src)
except PermissionError:
Expand All @@ -80,6 +55,6 @@ def batch_process(directory, prefix=None, start_number=1, extension=".jpg", conv
processed_files += 1
if progress_callback:
progress = int((processed_files / total_files) * 100)
progress_callback.emit(progress) # 使用 emit 发送信号
progress_callback(progress) # 调用回调函数

return count - start_number
return count - start_number
49 changes: 39 additions & 10 deletions SnapForge/ui.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# ui.py
import os
import sys

Expand Down Expand Up @@ -27,11 +26,20 @@ def __init__(self, directory, prefix, start_number, extension, convert_format, c

def run(self):
try:
processed_count = batch_process(self.directory, self.prefix, self.start_number, self.extension,
self.convert_format, self.compress_quality, self.progress_updated)
processed_count = batch_process(
self.directory,
self.prefix,
self.start_number,
self.extension,
self.convert_format,
self.compress_quality,
self.progress_updated
)
self.finished.emit(processed_count)
except Exception as e:
self.error_occurred.emit(str(e))
finally:
self.finished.emit(0) # 确保在异常情况下也能发送完成信号


class BatchRenameApp(QMainWindow):
Expand Down Expand Up @@ -143,14 +151,32 @@ def toggle_compress_input(self):

def start_processing(self):
directory = self.directory_input.text()
if not os.path.isdir(directory):
QMessageBox.critical(self, "错误", "目录路径无效。")
return

prefix = self.prefix_input.text() if self.rename_checkbox.isChecked() else None
start_number = int(self.start_number_input.text()) if self.rename_checkbox.isChecked() else 1

try:
start_number = int(self.start_number_input.text()) if self.rename_checkbox.isChecked() else 1
except ValueError:
QMessageBox.critical(self, "错误", "起始编号必须是一个正整数。")
return

extension = self.extension_input.text()
convert_format = self.convert_format_input.text() if self.convert_format_checkbox.isChecked() else None
compress_quality = int(self.compress_quality_input.text()) if self.compress_checkbox.isChecked() else None
if not extension.startswith("."):
extension = f".{extension}"

if not os.path.isdir(directory):
QMessageBox.critical(self, "错误", "目录路径无效。")
convert_format = self.convert_format_input.text().strip().lower() if self.convert_format_checkbox.isChecked() else None
if convert_format and not convert_format.startswith("."):
convert_format = f".{convert_format}"

try:
compress_quality = int(self.compress_quality_input.text()) if self.compress_checkbox.isChecked() else None
if compress_quality is not None and (compress_quality < 0 or compress_quality > 100):
raise ValueError
except ValueError:
QMessageBox.critical(self, "错误", "压缩质量必须是0到100之间的整数。")
return

self.process_button.setEnabled(False) # 禁用按钮
Expand All @@ -167,7 +193,10 @@ def update_progress(self, progress):
self.progress_bar.setValue(progress)

def processing_finished(self, processed_count):
self.result_label.setText(f"已成功处理 {processed_count} 个文件!")
if processed_count > 0:
self.result_label.setText(f"已成功处理 {processed_count} 个文件!")
else:
self.result_label.setText("处理失败或没有文件被处理。")
self.process_button.setEnabled(True) # 启用按钮

def processing_error(self, error_message):
Expand All @@ -180,4 +209,4 @@ def processing_error(self, error_message):
app = QApplication(sys.argv)
window = BatchRenameApp()
window.show()
sys.exit(app.exec())
sys.exit(app.exec())

0 comments on commit 1557667

Please sign in to comment.