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

Django中使用BytesIO获取图片大小与实际值不符该如何解决

问题根因

你的代码存在两处核心错误,导致获取的大小和实际值不符:

  1. 语法错误:image_file_size = img.tell() 这行调用对象错误。img是PIL的Image实例,它的tell()方法返回值不是文件大小,你应该调用存储了编码后图片的img_file(BytesIO实例)的tell()方法。
  2. 逻辑错误:你把用户上传的原始图片重新用JPEG格式压缩编码了一遍,计算出来的是重编码后的文件大小,和用户上传的原始文件大小自然不一致。

解决方案

根据你的实际需求二选一即可:

方案1:校验用户上传的原始图片大小(绝大多数场景用这个就行)

不需要调用PIL做编码处理,Django的上传文件对象自带size属性,直接读取即可,修改对应循环逻辑:

for x in images:
    # 直接读取原始文件大小,单位为字节
    image_file_size = x.size
    if image_file_size > 150 * 1024:
        failure = "图片大小不能超过150KB"
        return render(request, 'Main/document_upload.html', {'failure':failure})
    # 原有保存逻辑不变
    fs = FileSystemStorage()
    filename = fs.save(x.name, x)
    Doc1 = Doc(user_id = unq_id, upload = x, name = name)
    Doc1.save()
    success = "You have successfully added documents, proceed to 'My documents' to see your documents"

方案2:校验重编码为JPEG后的图片大小(如果你后续存储的是重编码后的图片)

修正语法错误,同时注意BytesIO的指针问题:

for x in images:
    img = Image.open(x)
    img_file = BytesIO()
    img.save(img_file, 'jpeg')
    # 修正为调用BytesIO实例的tell方法获取大小
    image_file_size = img_file.tell()
    if image_file_size > 150 * 1024:
        failure = "图片大小不能超过150KB"
        return render(request, 'Main/document_upload.html', {'failure':failure})
    # 注意要把BytesIO的指针移到开头才能正常读取内容保存
    img_file.seek(0)
    # 后续保存逻辑对应修改为存储img_file即可

额外注意

你的原代码还存在变量未定义的隐患:如果请求是GET方法,success变量没有提前赋值,渲染模板时会报错,建议在函数开头初始化success = ''。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 04:54:02