Python 实现图片缩略图可设置宽高

 zhangy  2025-04-07 14:51:05  161  6  0

在Python中,可以使用Pillow库(PIL的一个分支)来轻松实现图片缩略图功能:

安装Pillow

首先需要安装Pillow库:

pip install pillow

(支持多种模式)

from PIL import Image, ImageOps

def create_thumbnail_advanced(input_path, output_path, width=None, height=None, 
                            mode='fit', background=(255, 255, 255), quality=85):
    """
    高级缩略图生成函数
    :param input_path: 输入图片路径
    :param output_path: 输出缩略图路径
    :param width: 缩略图宽度
    :param height: 缩略图高度
    :param mode: 处理模式 ('fit':保持比例, 'stretch':拉伸, 'pad':填充, 'crop':裁剪)
    :param background: 填充模式下的背景颜色
    :param quality: 输出质量(1-100)
    """
    if not width and not height:
        raise ValueError("必须指定宽度或高度")
    
    try:
        with Image.open(input_path) as img:
            orig_width, orig_height = img.size
            
            # 计算新尺寸
            if mode == 'fit':
                if width and height:
                    ratio = min(width/orig_width, height/orig_height)
                elif width:
                    ratio = width/orig_width
                else:
                    ratio = height/orig_height
                new_width = int(orig_width * ratio)
                new_height = int(orig_height * ratio)
                img = img.resize((new_width, new_height), Image.LANCZOS)
                
            elif mode == 'stretch':
                if not width or not height:
                    raise ValueError("拉伸模式必须同时指定宽度和高度")
                img = img.resize((width, height), Image.LANCZOS)
                
            elif mode == 'pad':
                if not width or not height:
                    raise ValueError("填充模式必须同时指定宽度和高度")
                ratio = min(width/orig_width, height/orig_height)
                new_width = int(orig_width * ratio)
                new_height = int(orig_height * ratio)
                img = img.resize((new_width, new_height), Image.LANCZOS)
                new_img = Image.new("RGB", (width, height), background)
                offset = ((width - new_width) // 2, (height - new_height) // 2)
                new_img.paste(img, offset)
                img = new_img
                
            elif mode == 'crop':
                if not width or not height:
                    raise ValueError("裁剪模式必须同时指定宽度和高度")
                target_ratio = width / height
                orig_ratio = orig_width / orig_height
                if orig_ratio > target_ratio:
                    new_width = int(orig_height * target_ratio)
                    left = (orig_width - new_width) // 2
                    box = (left, 0, left + new_width, orig_height)
                else:
                    new_height = int(orig_width / target_ratio)
                    top = (orig_height - new_height) // 2
                    box = (0, top, orig_width, top + new_height)
                img = img.crop(box).resize((width, height), Image.LANCZOS)
                
            else:
                raise ValueError(f"未知模式: {mode}")
            
            # 保存图片
            if output_path.lower().endswith(('.jpg', '.jpeg')):
                img.save(output_path, quality=quality, optimize=True)
            else:
                img.save(output_path)
                
            print(f"缩略图已保存到: {output_path} ({img.width}x{img.height})")
            
    except Exception as e:
        print(f"处理图片时出错: {e}")

# 使用示例
create_thumbnail_advanced("original.jpg", "thumbnail_fit.jpg", width=300, height=200, mode='fit')
create_thumbnail_advanced("original.jpg", "thumbnail_stretch.jpg", width=300, height=200, mode='stretch')
create_thumbnail_advanced("original.jpg", "thumbnail_pad.jpg", width=300, height=200, mode='pad')
create_thumbnail_advanced("original.jpg", "thumbnail_crop.jpg", width=300, height=200, mode='crop')


注意事项

  1. Image.LANCZOS 是高质量的重采样滤波器,适合缩略图生成

  2. 对于JPEG图片,可以设置quality参数(1-100)控制质量

  3. 透明背景的PNG图片需要特殊处理,可能需要转换为RGBA模式

  4. 大图片处理时可能需要考虑内存使用情况

你可以根据具体需求选择合适的模式。


发布评论  
您至少需输入5字最多输入1000字(登录用户才可以评论)
评论内容