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

如何在Django中用PILLOW压缩上传图片?求完整使用文档

Django views.py 中使用 Pillow 实现图片压缩的完整方案

Hey there! I’ve been stuck on this exact issue before — getting Pillow to work smoothly with Django for image compression can feel frustrating when tutorials skip over the little details. Let’s put together a complete, tested implementation that you can use right away.

第一步:确保 Pillow 已安装

首先确认你的环境里装了 Pillow,如果没装,运行:

pip install pillow

第二步:编写可复用的图片压缩函数

先写一个通用的压缩函数,它能处理不同格式的图片(JPEG/PNG),支持尺寸调整和质量控制,放在你的views.py或者单独的utils文件里都可以:

from PIL import Image
import os
from django.conf import settings

def compress_image(image_path, output_path=None, quality=60, max_size=(1920, 1080)):
    """
    压缩图片并保存
    :param image_path: 原始图片的路径
    :param output_path: 压缩后图片的保存路径(默认覆盖原文件)
    :param quality: 压缩质量(1-100,JPEG有效;PNG建议用默认)
    :param max_size: 图片最大尺寸(宽, 高),超过则按比例缩放
    """
    if not output_path:
        output_path = image_path

    try:
        # 打开图片
        with Image.open(image_path) as img:
            # 处理透明度(PNG转RGB避免保存JPEG时出错)
            if img.mode in ("RGBA", "P"):
                img = img.convert("RGB")
            
            # 按比例缩放图片到指定最大尺寸
            img.thumbnail(max_size, Image.Resampling.LANCZOS)
            
            # 根据图片格式设置压缩参数
            file_ext = os.path.splitext(image_path)[1].lower()
            save_args = {}
            if file_ext in (".jpg", ".jpeg"):
                save_args["quality"] = quality
                save_args["optimize"] = True
            elif file_ext == ".png":
                save_args["optimize"] = True  # PNG用optimize参数优化
            
            # 保存压缩后的图片
            img.save(output_path, **save_args)
            return True
    except Exception as e:
        print(f"压缩图片出错: {str(e)}")
        return False

第三步:在 Django View 中使用这个函数

下面是几个常见场景的示例:

场景1:处理用户上传的图片(表单提交)

假设你有一个接收图片上传的View,在保存到模型之前先压缩:

from django.shortcuts import render, redirect
from .forms import ImageUploadForm
from .models import UploadedImage

def upload_and_compress(request):
    if request.method == "POST":
        form = ImageUploadForm(request.POST, request.FILES)
        if form.is_valid():
            # 先保存上传的图片到临时位置(Django默认会存在内存或临时文件)
            uploaded_image = form.cleaned_data["image"]
            # 获取图片的完整路径
            temp_path = os.path.join(settings.MEDIA_ROOT, uploaded_image.name)
            
            # 先把上传的文件写到磁盘(因为Pillow需要文件路径)
            with open(temp_path, "wb+") as f:
                for chunk in uploaded_image.chunks():
                    f.write(chunk)
            
            # 压缩图片(这里直接覆盖原文件,也可以指定新路径)
            compress_image(temp_path, quality=50)
            
            # 把压缩后的图片保存到模型
            instance = UploadedImage(image=uploaded_image)
            instance.save()
            
            # 删除临时文件(如果不需要的话)
            os.remove(temp_path)
            
            return redirect("success_page")
    else:
        form = ImageUploadForm()
    return render(request, "upload.html", {"form": form})

场景2:压缩模型中已存在的图片

如果你的模型里已经有图片,想要批量或单个压缩:

from .models import Product

def compress_product_images(request):
    # 获取所有带图片的Product对象
    products = Product.objects.filter(image__isnull=False)
    for product in products:
        # 获取图片的本地路径
        image_path = product.image.path
        # 压缩图片,覆盖原文件
        compress_image(image_path, quality=65)
    return render(request, "compress_done.html")

常见问题排查(为什么你之前可能失败了?)

  • 格式不兼容:比如直接把PNG图片存为JPEG而没有转成RGB模式,会报错
  • 路径错误:没有正确获取Django的MEDIA_ROOT,导致Pillow找不到文件
  • 权限问题:服务器没有写入目标路径的权限,检查文件夹的读写权限
  • 参数错误:给PNG图片设置quality参数(PNG的质量参数和JPEG不同,建议用optimize=True)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:39:37