From 4d4d6dbedfafeb6a65d8441ae9223282c8e0c75c Mon Sep 17 00:00:00 2001 From: aoxuan Date: Wed, 11 Jun 2025 22:14:09 +0800 Subject: [PATCH] =?UTF-8?q?refactor(app):=20=E9=87=8D=E6=9E=84=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E5=8E=8B=E7=BC=A9=E5=8A=9F=E8=83=BD=E5=B9=B6=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E7=B1=BB=E5=9E=8B=E6=B3=A8=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 使用 Path 对象替换字符串表示文件路径,提高代码可读性和功能 - 优化类型注解,包括函数参数和返回值- 重构 ImageUtils.compress_image_if_needed 方法,简化逻辑并提高性能 - 更新 notification.py 中使用该方法的代码,直接返回压缩后的 Path 对象 --- app/services/notification.py | 5 ++-- app/utils/ImageUtils.py | 46 ++++++++++++++++-------------------- 2 files changed, 23 insertions(+), 28 deletions(-) diff --git a/app/services/notification.py b/app/services/notification.py index 7ab2211..d5e17e9 100644 --- a/app/services/notification.py +++ b/app/services/notification.py @@ -273,12 +273,11 @@ class Notification(QObject): ) return f"使用企业微信群机器人推送通知时出错:{err}" - def CompanyWebHookBotPushImage(self, image_path: str, webhook_url: str) -> bool: + def CompanyWebHookBotPushImage(self, image_path: Path, webhook_url: str) -> bool: """使用企业微信群机器人推送图片通知""" try: # 压缩图片 - final_image_path = ImageUtils.compress_image_if_needed(str(image_path)) - final_image_path = Path(final_image_path) + final_image_path = ImageUtils.compress_image_if_needed(image_path) # 检查图片是否存在 if not final_image_path.exists(): diff --git a/app/utils/ImageUtils.py b/app/utils/ImageUtils.py index 649f687..64b2447 100644 --- a/app/utils/ImageUtils.py +++ b/app/utils/ImageUtils.py @@ -1,6 +1,7 @@ import base64 import hashlib -import os +from pathlib import Path + from PIL import Image class ImageUtils: @@ -23,44 +24,39 @@ class ImageUtils: return hashlib.md5(image_data).hexdigest() @staticmethod - def compress_image_if_needed(image_path, max_size_mb=2): + def compress_image_if_needed(image_path: Path, max_size_mb=2) -> Path: """ - 如果图片大于max_size_mb(默认2MB),则压缩到max_size_mb以内, - 返回压缩后文件路径(压缩文件与原图同目录,命名为xxx_compressed.xxx), - 如果不超过则返回原文件路径 + 如果图片大于max_size_mb,则压缩并覆盖原文件,返回原始路径(Path对象) """ - if hasattr(Image, "Resampling"): # Pillow 9.1.0及以后 RESAMPLE = Image.Resampling.LANCZOS - else: # Pillow 老版本 + else: RESAMPLE = Image.ANTIALIAS max_size = max_size_mb * 1024 * 1024 - file_size = os.path.getsize(image_path) - if file_size <= max_size: - return image_path # 小于2MB,直接返回原路径 - - # 只支持JPEG、PNG压缩 - file_root, file_ext = os.path.splitext(image_path) - compressed_path = f"{file_root}_compressed{file_ext}" + if image_path.stat().st_size <= max_size: + return image_path img = Image.open(image_path) - quality = 90 if file_ext.lower() in ['.jpg', '.jpeg'] else None - step = 5 # 每次降低5质量或5%尺寸 + suffix = image_path.suffix.lower() + quality = 90 if suffix in [".jpg", ".jpeg"] else None + step = 5 - # 如果是JPG/JPEG - if file_ext.lower() in ['.jpg', '.jpeg']: + if suffix in [".jpg", ".jpeg"]: while True: - img.save(compressed_path, quality=quality, optimize=True) - if os.path.getsize(compressed_path) <= max_size or quality <= 10: + img.save(image_path, quality=quality, optimize=True) + if image_path.stat().st_size <= max_size or quality <= 10: break quality -= step - # PNG 只能调整尺寸来压缩 - elif file_ext.lower() == '.png': + elif suffix == ".png": width, height = img.size while True: - img.save(compressed_path, optimize=True) - if os.path.getsize(compressed_path) <= max_size or width <= 200 or height <= 200: + img.save(image_path, optimize=True) + if ( + image_path.stat().st_size <= max_size + or width <= 200 + or height <= 200 + ): break width = int(width * 0.95) height = int(height * 0.95) @@ -68,4 +64,4 @@ class ImageUtils: else: raise ValueError("仅支持JPG/JPEG和PNG格式图片的压缩。") - return compressed_path + return image_path