无需本地存储如何获取PIL Image对象的文件大小
from io import BytesIO from PIL import Image # 你的原有代码,修复了concat_image_auto的参数引用错误 def concat_image_auto(image1,image2,size_image): # 这里原来误用了全局变量size,改成参数传入的size_image避免报错 if size_image[0]>size_image[1]: ## 垂直拼接 dst = Image.new('RGB', (size_image[0], image1.height + image2.height)) dst.paste(image1, (0, 0)) dst.paste(image2, (0, image1.height)) else: ## 水平拼接 dst = Image.new('RGB', (image1.width + image2.width, size_image[1])) dst.paste(image1, (0, 0)) dst.paste(image2, (image1.width, 0)) return dst image1 = Image.open('my_first_image.jpg') image2 = Image.open('my_second_image.jpg') max_w = max(image1.size[0],image2.size[0]) max_h = max(image1.size[1],image2.size[1]) size = (max_w,max_h) image1 = image1.resize(size) image2 = image2.resize(size) # 拼接图片 file_merged = concat_image_auto(image1,image2,size) # -------------------以下是大小检测+压缩逻辑------------------- # 设定允许的最大文件大小,示例为1MB,单位为字节,可自行调整 MAX_ALLOWED_SIZE = 1 * 1024 * 1024 def get_image_file_size(img, format='JPEG', quality=95): """计算图片在指定导出格式下的文件大小,全程在内存中操作""" buffer = BytesIO() img.save(buffer, format=format, quality=quality, optimize=True) # 返回缓冲区的字节数,就是对应文件的大小 return buffer.tell() def compress_image(img, target_size, format='JPEG', start_quality=95, min_quality=10): """压缩图片到不超过指定大小,返回压缩后的PIL Image对象""" current_quality = start_quality current_size = get_image_file_size(img, format, current_quality) # 大小已经符合要求直接返回原对象 if current_size <= target_size: return img # 逐步降低质量直到符合要求或达到最低质量阈值 while current_size > target_size and current_quality >= min_quality: current_quality -= 5 current_size = get_image_file_size(img, format, current_quality) # 生成最终压缩后的PIL对象 buffer = BytesIO() img.save(buffer, format=format, quality=current_quality, optimize=True) buffer.seek(0) return Image.open(buffer) # 执行压缩,得到最终的PIL Image对象 compressed_merged_image = compress_image(file_merged, MAX_ALLOWED_SIZE, format='JPEG')
注意说明
- 所有操作都通过内存缓冲区
BytesIO完成,没有任何本地文件写入,符合你的要求 - 可以根据需求调整参数:包括最大大小阈值、最低压缩质量、每次降低质量的步长、导出格式(如果需要PNG就把format参数改成'PNG',注意PNG的quality取值范围是0-9,数值越大压缩率越高,需要单独调整逻辑中的quality相关参数)
- 如果你不需要保留原拼接图片对象,可以直接用
file_merged = compress_image(...)覆盖原变量即可
内容的提问来源于stack exchange,提问作者Ninja
相关产品推荐
相关产品推荐

