You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何降低WebP图片分辨率而非仅压缩文件大小?

如何用Python降低WebP图片的分辨率

问题背景

尝试通过Python代码压缩WebP图片,原代码仅通过调整JPEG保存质量减小了文件大小(从42.8kB降至8kB),但图片分辨率仍保持500x450不变,仅画质模糊。需要实现降低图片分辨率的效果,而非单纯压缩文件体积。

原代码如下:

import os
import shutil as sh
import cv2
import sys
import PIL
from PIL import Image

img = PIL.Image.open("target.webp")

width, height = img.size
print(width, height)

# define a function for
# compressing an image
def compressMe(file, verbose=False):
    # Get the path of the file
    filepath = os.path.join(os.getcwd(),
                            file)

    # open the image
    picture = Image.open(filepath)

    # Save the picture with desired quality
    # To change the quality of image,
    # set the quality variable at
    # your desired level, The more
    # the value of quality variable
    # and lesser the compression
    picture.save("Compressed_" + file,
                 "JPEG",
                 optimize=True,
                 quality=10)
    return


# Define a main function
def main():
    verbose = False

    # checks for verbose flag
    if (len(sys.argv) > 1):

        if (sys.argv[1].lower() == "-v"):
            verbose = True

    # finds current working dir
    cwd = os.getcwd()

    formats = ('.jpg', '.jpeg')

    # looping through all the files
    # in a current directory
    for file in os.listdir(cwd):

        # If the file format is JPG or JPEG
        if os.path.splitext(file)[1].lower() in formats:
            print('compressing', file)
            compressMe(file, verbose)

    print("Done")

if __name__ == "__main__":
    main()

compressMe('target.webp')
img2 = PIL.Image.open("Compressed_target.webp")
PIL.Image._show(img2)

width, height = img2.size
print(width, height)

问题分析

原代码的compressMe函数仅修改了图片保存时的JPEG质量参数,没有对图片进行**缩放(resize)**操作,因此分辨率保持原始尺寸不变,只是通过降低画质来减小文件大小,导致图片模糊但分辨率未变。

解决方案

要降低分辨率,需要在处理流程中加入图片缩放步骤,通过PIL库的Image.resize()方法调整图片的宽高尺寸,同时可结合质量压缩进一步优化文件大小。

修改后的代码

import os
import sys
from PIL import Image

def resize_and_compress(file, target_width=None, target_height=None, quality=75, verbose=False):
    filepath = os.path.join(os.getcwd(), file)
    picture = Image.open(filepath)
    original_width, original_height = picture.size

    # 计算缩放后的尺寸:支持指定单维度或按比例自动计算
    if target_width and not target_height:
        ratio = target_width / original_width
        target_height = int(original_height * ratio)
    elif target_height and not target_width:
        ratio = target_height / original_height
        target_width = int(original_width * ratio)
    elif not target_width and not target_height:
        # 默认按50%比例缩放
        target_width = int(original_width * 0.5)
        target_height = int(original_height * 0.5)

    # 使用LANCZOS滤镜缩放,保证画质
    resized_picture = picture.resize((target_width, target_height), Image.Resampling.LANCZOS)

    # 保存时保留原图片格式(避免WebP转JPEG的额外损失)
    output_filename = f"Resized_Compressed_{file}"
    resized_picture.save(output_filename, format=picture.format, optimize=True, quality=quality)

    if verbose:
        print(f"原尺寸: {original_width}x{original_height} → 新尺寸: {target_width}x{target_height}")
        print(f"已生成文件: {output_filename}")
    return output_filename

def main():
    verbose = False
    target_width = None
    target_height = None
    quality = 75

    # 解析命令行参数,支持自定义分辨率、质量和 verbose 模式
    args = sys.argv[1:]
    i = 0
    while i < len(args):
        if args[i].lower() == "-v":
            verbose = True
        elif args[i].lower() == "-w":
            target_width = int(args[i+1])
            i += 1
        elif args[i].lower() == "-h":
            target_height = int(args[i+1])
            i += 1
        elif args[i].lower() == "-q":
            quality = int(args[i+1])
            i += 1
        i += 1

    cwd = os.getcwd()
    # 支持WebP、JPG、JPEG格式
    supported_formats = ('.webp', '.jpg', '.jpeg')

    for file in os.listdir(cwd):
        file_ext = os.path.splitext(file)[1].lower()
        if file_ext in supported_formats:
            print(f"正在处理: {file}")
            resize_and_compress(file, target_width, target_height, quality, verbose)

    print("所有文件处理完成")

if __name__ == "__main__":
    main()

# 单独测试目标WebP文件,指定宽度为250,质量75
output_file = resize_and_compress('target.webp', target_width=250, quality=75, verbose=True)
img2 = Image.open(output_file)
print(f"新图片分辨率: {img2.size[0]}x{img2.size[1]}")
img2.show()

关键说明

  • 缩放逻辑:支持手动指定目标宽度/高度,或按比例自动计算;未指定时默认按50%比例缩放
  • 画质保障:使用Image.Resampling.LANCZOS滤镜(PIL 9.1.0+版本,旧版本可替换为Image.LANCZOS),缩放后画质优于默认滤镜
  • 格式保留:保存时使用原图片的格式(如WebP),避免格式转换带来的画质损失
  • 参数控制:通过命令行参数可灵活调整分辨率、压缩质量和输出详情,例如:
    • python script.py -w 300 -q 80 -v:将图片缩放到宽度300,质量80,显示详细信息

内容的提问来源于stack exchange,提问作者GR_ Gamer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 03:06:39