From 3832997ac57d1464a677c39cfdfccd11d7453afb Mon Sep 17 00:00:00 2001 From: liuwei Date: Mon, 26 May 2025 10:08:29 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E5=8F=A5=E6=9F=84=E5=8D=A0?= =?UTF-8?q?=E7=94=A8=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugins/xiuren_image/meitu_dl.py | 11 +++-- plugins/xiuren_image/xiuren_pdf.py | 68 +++++++++++++++--------------- sehuatang/shehuatang.py | 40 +++++++++--------- 3 files changed, 58 insertions(+), 61 deletions(-) diff --git a/plugins/xiuren_image/meitu_dl.py b/plugins/xiuren_image/meitu_dl.py index d5b0417..b7a46aa 100644 --- a/plugins/xiuren_image/meitu_dl.py +++ b/plugins/xiuren_image/meitu_dl.py @@ -150,12 +150,11 @@ def download_image(img_url, folder_path, img_index, max_retries=3): time.sleep(2 * (attempt + 1)) continue - img = Image.open(BytesIO(response.content)).convert('RGB') - img_name = f"{img_index:03d}.jpg" - img_path = os.path.join(folder_path, img_name) - - img.save(img_path, 'JPEG', quality=95) - logger.info(f"已下载并转换为JPG: {img_path}") + with Image.open(BytesIO(response.content)).convert('RGB') as img: + img_name = f"{img_index:03d}.jpg" + img_path = os.path.join(folder_path, img_name) + img.save(img_path, 'JPEG', quality=95) + logger.info(f"已下载并转换为JPG: {img_path}") return True except Exception as e: diff --git a/plugins/xiuren_image/xiuren_pdf.py b/plugins/xiuren_image/xiuren_pdf.py index 8ef0c14..877de9b 100644 --- a/plugins/xiuren_image/xiuren_pdf.py +++ b/plugins/xiuren_image/xiuren_pdf.py @@ -8,45 +8,45 @@ import io def compress_image(image_path, target_size_kb=300): """快速压缩图片到目标大小(单位:KB)""" - img = PILImage.open(image_path) + with PILImage.open(image_path) as img: + # 调整图片尺寸,保持宽高比 + # 如果图片有透明度,转换为RGB + if img.mode in ('RGBA', 'P'): + img = img.convert('RGB') - # 如果图片有透明度,转换为RGB - if img.mode in ('RGBA', 'P'): - img = img.convert('RGB') + # 获取原始文件大小(KB) + original_size_kb = os.path.getsize(image_path) / 1024 - # 获取原始文件大小(KB) - original_size_kb = os.path.getsize(image_path) / 1024 + # 如果原始大小已小于目标大小,直接返回原始数据 + if original_size_kb <= target_size_kb: + output = io.BytesIO() + img.save(output, format='JPEG', quality=85) + return output.getvalue() + + # 根据原始大小和目标大小预估初始质量 + # 假设质量与文件大小近似线性关系,设置一个初始值 + estimated_quality = min(95, max(10, int(85 * (target_size_kb / original_size_kb)))) - # 如果原始大小已小于目标大小,直接返回原始数据 - if original_size_kb <= target_size_kb: output = io.BytesIO() - img.save(output, format='JPEG', quality=85) - return output.getvalue() + img.save(output, format='JPEG', quality=estimated_quality) + size_kb = len(output.getvalue()) / 1024 - # 根据原始大小和目标大小预估初始质量 - # 假设质量与文件大小近似线性关系,设置一个初始值 - estimated_quality = min(95, max(10, int(85 * (target_size_kb / original_size_kb)))) + # 如果预估结果偏差较大,使用二分法调整(最多尝试3次) + low, high = 10, 95 + for _ in range(3): + if size_kb <= target_size_kb * 0.9 or size_kb >= target_size_kb * 1.1: # 允许±10%偏差 + quality = (low + high) // 2 + output.seek(0) + output.truncate(0) + img.save(output, format='JPEG', quality=quality) + size_kb = len(output.getvalue()) / 1024 - output = io.BytesIO() - img.save(output, format='JPEG', quality=estimated_quality) - size_kb = len(output.getvalue()) / 1024 - - # 如果预估结果偏差较大,使用二分法调整(最多尝试3次) - low, high = 10, 95 - for _ in range(3): - if size_kb <= target_size_kb * 0.9 or size_kb >= target_size_kb * 1.1: # 允许±10%偏差 - quality = (low + high) // 2 - output.seek(0) - output.truncate(0) - img.save(output, format='JPEG', quality=quality) - size_kb = len(output.getvalue()) / 1024 - - if size_kb > target_size_kb: - high = quality - 1 + if size_kb > target_size_kb: + high = quality - 1 + else: + low = quality + 1 else: - low = quality + 1 - else: - break + break return output.getvalue() @@ -85,8 +85,8 @@ def create_pdf_from_images(directory, output_pdf): compressed_image_data = compress_image(image_file) # 从压缩字节数据中读取图片以获取新尺寸 - compressed_img = PILImage.open(io.BytesIO(compressed_image_data)) - img_width, img_height = compressed_img.size + with PILImage.open(io.BytesIO(compressed_image_data)) as compressed_img: + img_width, img_height = compressed_img.size # 设置目标宽度(适应A3页面宽度,最大800点) target_width = 800 diff --git a/sehuatang/shehuatang.py b/sehuatang/shehuatang.py index d740f29..68142eb 100644 --- a/sehuatang/shehuatang.py +++ b/sehuatang/shehuatang.py @@ -182,27 +182,25 @@ def fetch_and_create_pdf(url): if image: try: # 使用PIL处理图片尺寸 - img = PILImage.open(image) - img_width, img_height = img.size - - # 计算缩放比例,确保图片适应页面 - scale_width = max_image_width / img_width - scale_height = max_image_height / img_height - scale = min(scale_width, scale_height, 1.0) # 不超过原始大小 - - # 计算新的尺寸 - new_width = img_width * scale - new_height = img_height * scale - - # 重置文件指针 - image.seek(0) - img_stream = BytesIO(image.getvalue()) - - # 添加图片到内容中,使用计算后的尺寸 - content.append(Image(img_stream, width=new_width, height=new_height)) - content.append(Spacer(1, 4)) - - print(f"处理图片: 原始尺寸 {img_width}x{img_height}, 新尺寸 {new_width}x{new_height}") + with PILImage.open(image) as img: + img_width, img_height = img.size + # 计算缩放比例,确保图片适应页面 + scale_width = max_image_width / img_width + scale_height = max_image_height / img_height + scale = min(scale_width, scale_height, 1.0) # 不超过原始大小 + + # 计算新的尺寸 + new_width = img_width * scale + new_height = img_height * scale + + # 重置文件指针 + image.seek(0) + img_stream = BytesIO(image.getvalue()) + + # 添加图片到内容中,使用计算后的尺寸 + content.append(Image(img_stream, width=new_width, height=new_height)) + content.append(Spacer(1, 4)) + print(f"处理图片: 原始尺寸 {img_width}x{img_height}, 新尺寸 {new_width}x{new_height}") except Exception as e: print(f"处理图片时出错: {e}")