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

Django模型ImageField如何接入缩放函数实现图片上传前压缩

Django ImageField 接入自动压缩实现方案

你不需要修改ImageField的基础字段定义,通过重写模型的save方法,在文件持久化到存储前调用缩放压缩逻辑即可,该方案对admin后台上传、前端接口上传等所有入口生效。


第一步:调整缩放函数适配1MB大小要求

你现有的函数仅按固定宽高缩放,无法保证最终文件大小落在1MB以内,补充质量循环压缩逻辑即可:

import io
import os
from PIL import Image
from django.core.files.base import ContentFile

def compress_image(input_image, target_size=1024*1024, width=600, height=None):
    """
    压缩图片到指定大小以内
    :param input_image: 上传的图片文件对象/图片路径
    :param target_size: 目标文件大小,单位字节,默认1MB
    :param width: 缩放最大宽度
    :param height: 缩放最大高度
    """
    img = Image.open(input_image)
    # 处理宽高缩放
    w, h = img.size
    if width and height:
        max_size = (width, height)
    elif width:
        max_size = (width, h)
    elif height:
        max_size = (w, height)
    else:
        raise ValueError("Width or height required!")
    # Pillow 9.1.0以下版本替换为 Image.ANTIALIAS
    img.thumbnail(max_size, Image.Resampling.LANCZOS)
    # 统一转RGB避免透明通道存JPEG报错
    if img.mode in ("RGBA", "P"):
        img = img.convert("RGB")
    # 循环调整质量压缩到目标大小
    quality = 95
    while quality >= 10:
        img_io = io.BytesIO()
        img.save(img_io, format="JPEG", quality=quality, optimize=True)
        img_size = img_io.tell()
        if img_size <= target_size:
            break
        quality -= 5
    img_io.seek(0)
    return ContentFile(img_io.read())

第二步:重写模型save方法接入压缩逻辑

在你的模型类里重写save方法,判断图片字段有新上传文件时,调用压缩函数替换原有文件对象即可:

from django.db import models

class SellerInfo(models.Model):
    # 注意:原字段名doucment_image存在拼写错误,可按需修正
    document_image = models.ImageField(upload_to='sellerinfo', null=True, blank=True)
    # 其他业务字段...

    def save(self, *args, **kwargs):
        # 仅当图片字段有新上传的未提交文件时触发压缩,避免重复压缩
        if self.document_image and not self.document_image._committed:
            compressed_img = compress_image(self.document_image)
            original_name = os.path.basename(self.document_image.name)
            # 替换字段文件为压缩后的内容,暂不触发save
            self.document_image.save(original_name, compressed_img, save=False)
        super().save(*args, **kwargs)

注意事项

  • 压缩逻辑放在模型save层,所有上传入口(admin后台、表单、API接口)都会自动触发压缩,不需要单独在admin类中编写额外逻辑
  • 可以根据业务需求调整width初始值、压缩质量递减步长,平衡图片清晰度和文件大小
  • 如果需要保留PNG等带透明通道的原格式,可以在压缩函数里加格式判断分支,不要统一转JPEG
  • 如果你使用第三方云存储(OSS/COS等),该逻辑同样生效,处理流程在文件上传到云存储前完成

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 21:57:22