使用python压缩JPG图片

2025年2月7日

  1. 将大于5mb的jpg格式的照片压缩到5mb以下
    • 代码为
    import os
    from PIL import Image
    
    def compress_image_if_needed(image_path, max_size_mb=5):
        # 获取图片的原始大小
        original_size_mb = os.path.getsize(image_path) / (1024 * 1024)
    
        # 如果图片超过最大限制,则进行压缩
        if original_size_mb > max_size_mb:
            # 打开图片
            img = Image.open(image_path)
    
            # 计算新的质量
            quality = 95
            while quality > 20 and os.path.getsize(image_path) / (1024 * 1024) > max_size_mb:
                # 保存图片到临时文件
                temp_path = image_path + '.temp'
                img.save(temp_path, 'JPEG', quality=quality)
    
                # 如果临时文件小于或等于最大大小,则替换原文件
                if os.path.getsize(temp_path) / (1024 * 1024) <= max_size_mb:
                    # 删除掉源文件
                    os.remove(image_path)
                    # 将临时文件的名称修改成源文件
                    os.rename(temp_path, image_path)
                else:
                    # 否则,删除临时文件
                    os.remove(temp_path)
                quality -= 5
            print(
                f"图片 {image_path} 已压缩至 {quality + 5}% 质量,大小为 {os.path.getsize(image_path) / (1024 * 1024):.2f} MB")
        else:
            print(f"图片 {image_path} 大小为 {original_size_mb:.2f} MB,无需压缩")
    
    1. 函数定义:
      1. def compress_image_if_needed(image_path, max_size_mb=5)::定义了一个名为compress_image_if_needed的函数,接受两个参数:image_path(图片文件的路径)和max_size_mb(允许的最大文件大小,单位为MB,默认值为5MB)。
    2. 获取图片原始大小:
      1. original_size_mb = os.path.getsize(image_path) / (1024 * 1024):使用os.path.getsize函数获取图片的原始文件大小(以字节为单位),然后将其转换为MB以便于比较。
    3. 判断是否需要压缩:
      1. if original_size_mb > max_size_mb::判断图片的原始大小是否超过了允许的最大文件大小。如果超过了,则需要压缩图片。
    4. 打开图片文件:
      1. img = Image.open(image_path):使用PIL库中的Image.open方法打开图片文件,以便后续进行压缩处理。
    5. 压缩图片过程:
      1. quality = 95:初始化图片的质量为95%。
      2. while quality > 20 and os.path.getsize(image_path) / (1024 * 1024) > max_size_mb::使用一个while循环来不断尝试压缩图片,直到图片大小不超过最大文件大小或质量降低到20%为止。
      3. img.save(temp_path, 'JPEG', quality=quality):使用PIL库中的save方法将图片以JPEG格式保存,质量设置为当前的quality值。
      4. os.remove(image_path):如果压缩后的图片大小满足要求,则删除原始图片文件。
      5. os.remove(temp_path):无论是否满足要求,都会删除临时文件,因为在这个代码片段中,临时文件和原始文件的路径是相同的。
      6. quality -= 5:每次循环中将质量降低5%,以尝试进一步减小图片大小。
    6. 输出压缩结果:
      1. print(f"图片 {image_path} 已压缩至 {quality + 5}% 质量,大小为 {os.path.getsize(image_path) / (1024 * 1024):.2f} MB"):如果图片经过压缩后满足大小要求,则打印压缩后的图片质量和文件大小。
      2. print(f"图片 {image_path} 大小为 {original_size_mb:.2f} MB,无需压缩"):如果图片的原始大小已经满足要求,则直接打印图片的原始大小,并提示无需压缩。
  2. 如何批量压缩图片
    • 批量调用代码为
    def find_files(directory, extension):
        for root, dirs, files in os.walk(directory):
            for file in files:
                if file.endswith(extension):
                    # print(os.path.join(root, file))
                    compress_image_if_needed(os.path.join(root, file))
    
    1. 函数定义:def find_files(directory, extension):
      1. find_files 是函数的名称。
      2. directory 是参数,表示要搜索的目录路径。
      3. extension 是参数,表示要查找的文件扩展名,例如 .jpg 或 .png。
    2. 遍历目录树:for root, dirs, files in os.walk(directory):
      1. os.walk(directory) 是一个生成器,它会生成目录树中的所有目录和文件。
      2. root 表示当前正在遍历的目录路径。
      3. dirs 是一个列表,包含当前目录下的所有子目录名。
      4. files 是一个列表,包含当前目录下的所有文件名。
  3. 如何根据图片大小动态的调整压缩的步长
    • 代码为
    from PIL import Image
    import os
    
    def compress_image_if_needed(image_path,max_size_mb=5):
        # 获取图片的原始大小
        original_size_mb = os.path.getsize(image_path) / (1024 * 1024)
        current_size_mb = original_size_mb
    
        # 如果图片超过最大限制,则进行压缩
        if current_size_mb > max_size_mb:
            # 打开图片
            img = Image.open(image_path)
    
            # 初始化质量
            quality = 95
    
            while quality > 20 and current_size_mb > max_size_mb:
                # 计算差距
                size_diff = current_size_mb - max_size_mb
    
                # 根据差距动态调整步长
                step = max(1,int(10*(size_diff/max_size_mb)))
    
                # 保存图片到临时文件
                temp_path = image_path + '.temp'
                img.save(temp_path,'JPEG',quality=quality)
    
                # 检查临时文件的大小
                current_size_mb = os.path.getsize(temp_path) / (1024 * 1024)
    
                # 如果临时文件小于或等于最大大小,则替换原文件
                if current_size_mb <= max_size_mb:
                    os.remove(image_path)
                    os.rename(temp_path,image_path)
                else:
                    os.remove(temp_path)
                
                quality -= step
    
    • 上述代码中,自动调整步长的数学公式是:step = max(1, int(10 * (size_diff / max_size_mb)))
    • size_diff: 这是当前图片大小与最大允许大小之间的差距。
    • step: 这是每次压缩时减少的质量值。
      • 10 * (size_diff / max_size_mb): 这部分计算的是一个比例值,表示当前大小超出最大允许大小的比例。乘以10是为了将这个比例值放大到一个更合理的步长范围。
      • int(...): 将比例值转换为整数,以便作为步长使用。
      • max(1, ...): 确保步长至少为1。如果计算出的步长小于1,则直接使用1作为步长。
    • 例如:
    • 如果当前图片大小为10 MB,最大允许大小为5 MB,则 size_diff 为 5 MB。
    • 计算步长时,10 * (5 / 5) 等于 10,所以 step 为 10。
    • 如果当前图片大小为5.5 MB,最大允许大小为5 MB,则 size_diff 为 0.5 MB。
    • 计算步长时,10 * (0.5 / 5) 等于 1,所以 step 为 1。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值