GIS数据共享:官方网站

python

当前位置:首页 > language > python

Python将图片压缩到指定大小以下并备份原始数据

Python将图片压缩到指定大小以下并备份原始数据

本代理示例可以实现:

  1. 批量压缩指定目录下的图片且支持png压缩;

  2. 压缩时支持对原图片备份;

  3. 可以指定最大图片大小;

对上述参数,可在代码中直接修改;

如果你没有PIL库,可使用pip install pillow安装

import os,io  
from PIL import Image
import shutil
 
"""批量压缩图片大小:首先判断是否为图片,获取图片大小,判断是否大于300KB,
   对于小于300KB的不做处理,对于大于300KB的,在锁定纵横比的情况下,压缩至290KB。
   根据以上要求,遍历所有文件夹内的图片及嵌套文件内的图片进行处理。"""
 
 
def get_file_size(file_path):  
    """获取文件大小,单位为KB"""  
    return os.path.getsize(file_path) / 1024  
 
def compress_image(image_path, filetype, target_size_kb=290):  #为确保图片大小压缩后小于300kb,程序指标设置为290.
    """在保持纵横比的情况下压缩图片到指定大小(KB)附近"""
    print(filetype)
    original_size = get_file_size(image_path)  
    if original_size <= target_size_kb:  
        print(f"跳过 {image_path}:原始大小 {original_size:.2f} KB,小于或等于目标大小。")  
        return
    else:
        if os.path.exists(image_path + "bak") == False:
            shutil.copy(image_path, image_path + "bak")
           
    if filetype == "png":
        original_image = Image.open(image_path)
        width, height = original_image.size
        print(f"The original image size is {width} wide x {height} high")
        while True:
            width = int(float(width) * 0.99)
            height = int(float(height) * 0.99)
            resized_image = original_image.resize((width, height))
            resized_image.save(image_path)

            if width < 10 or height < 10:
                print(f"警告:无法将 {image_path} 压缩到 {target_size_kb} KB 以下,使用最低质量。")
                break

            img = Image.open(image_path)
            img_byte_arr = io.BytesIO()  
            img.save(img_byte_arr, format=filetype)  
            img_byte_arr = img_byte_arr.getvalue()  
            compressed_size = len(img_byte_arr) / 1024
            # 如果大小接近或小于目标大小,则退出循环  
            if compressed_size <= target_size_kb:
                print(f"压缩完成")
                break  
           
    else:
        img = Image.open(image_path)  
        # 获取图片原始尺寸  
        original_width, original_height = img.size  
     
        # 压缩比从100%开始尝试,逐步降低  
        quality = 95  
        while True:  
            # 保存图片到内存(不保存到磁盘),以评估压缩后的大小  
            img_byte_arr = io.BytesIO()  
            img.save(img_byte_arr, format='JPEG', quality=quality)  
            img_byte_arr = img_byte_arr.getvalue()  
            compressed_size = len(img_byte_arr) / 1024  
     
            # 如果大小接近或小于目标大小,则退出循环  
            if compressed_size <= target_size_kb:
                print(f"压缩完成")
                break
     
            # 否则,降低质量并继续尝试  
            quality -= 5
            print(compressed_size)
            print(quality)
            if quality < 10:  
                print(f"警告:无法将 {image_path} 压缩到 {target_size_kb} KB 以下,使用最低质量。")  
                break  
     
        # 如果需要,将压缩后的图片写回文件(这里演示不实际写入)  
        img.save(image_path, format='JPEG', quality=quality)  
     
        print(f"压缩 {image_path}:原始大小 {original_size:.2f} KB,压缩后大小 {compressed_size:.2f} KB。")  
 
def traverse_and_compress(root_dir):
    """遍历指定目录及其子目录,并压缩大于300KB的图片"""  
    for root, dirs, files in os.walk(root_dir):
        for file in files:
            if file.lower().endswith(('.png', '.jpg')):
                # if file.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp', '.gif')):
                file_path = os.path.join(root, file)
                filetype = file.split(".")[-1]
                compress_image(file_path, filetype)
 
# 设置要遍历的根目录  
root_directory = r"D:\cache\download\files_R4nxK.tar\files_R4nxK\files\upload"  # 替换为需要处理的图片所在文件夹路径
traverse_and_compress(root_directory)


扫码查看

相关内容

文章评论

表情

共 0 条评论,查看全部
  • 这篇文章还没有收到评论,赶紧来抢沙发吧~

热门标签