设置图像大小限制并根据需要调整图像大小

Posted

技术标签:

【中文标题】设置图像大小限制并根据需要调整图像大小【英文标题】:Set image size limit and resize image if is needed 【发布时间】:2016-08-21 00:59:27 【问题描述】:

我在我的表单中使用django-ckeditor 一些<textarea> 并使用widget=CKEditorUploadingWidget() 以便我可以上传图片,这工作正常但现在我需要设置1mb 作为图片的大小限制。

我的第一个问题是如何限制大小?如果可能我更喜欢在django-ckeditor 配置中配置限制,这可能吗?或者我必须在服务器中进行。

我的第二个问题是,如果图像大于 1mb,我需要在POST 中调整图像的大小,也许将重量和高度减半,如果仍然大于 1mb,则重复该过程,直到大小小于 1mb,关键是用户只需选择图像,应用程序会完成所有工作,而用户不必自己调整图像大小。

我的最后一个问题是,如果我需要在客户端执行所有这些处理,最好使用JQueryPythonPillow 并处理视图中的图像?

我真的迷失了,任何帮助真的很感激。

【问题讨论】:

【参考方案1】:

还可以在 models.py 中限制图像。

在你的models.py中放置一个类似这样的函数。

def validate_image(image):
    file_size = image.file.size
    limit_kb=settings.LIMIT_KB
    if file_size > limit_kb * 1024:
        raise ValidationError("Max size of file is %s KB" % limit_kb)

这假设你有:

from django.core.exceptions import ValidationError

它还假设您在 settings.py 中创建了一个常量 LIMIT_KB。

然后在添加字段时包括验证:

image = models.ImageField(upload_to=image_path,validators=[validate_image])

图像大小现在将受到模型的限制,并在使用表单时被捕获。

【讨论】:

【参考方案2】:

有很多可以讨论的内容。另一方面,担心图像大小检查基本上有两个不同的问题。 1) 客户端和 2) 服务器端。所以让我们分开吧。

服务器端

这是两者中最重要的部分。是的,客户端可以帮助减小图像的大小或通知用户他们尝试上传的图像太大,但最终您希望服务器决定什么是可接受的。

所以,在 Django 中,您可以做一些事情。

1) 限制文件大小 - 在您的设置中,您可以放置​​以下代码

# Add to your settings file
MAX_UPLOAD_SIZE = "1048576"

制作一个像下面这样的图像大小检查器,并运行它来检查'image_field'的大小(名称可能会改变)。如果 'image_field' 太大,此代码会返回验证错误。

#Add to a form containing a FileField and change the field names accordingly.
from django.template.defaultfilters import filesizeformat
from django.utils.translation import ugettext_lazy as _
from django.conf import settings

def check_image_field_size(self):
    content = self.cleaned_data.get('image_field')
    if content._size > settings.MAX_UPLOAD_SIZE:
        raise forms.ValidationError(_('Please keep filesize under %s. Current filesize %s') % (filesizeformat(settings.MAX_UPLOAD_SIZE), filesizeformat(content._size)))
    return content

source

这将防止上传的文件大小超过 1MB,期间。

2) 调整图片大小 - 使用 PIL(Pillow)调整图片大小。

import StringIO
from PIL import Image
from io import BytesIO

# get the image data from upload
image_field = self.cleaned_data.get('image_field')
image_file = StringIO.StringIO(image_field.read())
image = Image.open(image_file)

# like you said, cut image dimensions in half
w, h = image.size
image = image.resize((w/2, h/2), Image.ANTIALIAS)

# check if the image is small enough 
new_img_file = BytesIO()
image.save(new_img_file, 'png')
image_size = new_img_file.tell() 

# if the image isn't small enough, repeat the previous until it is.

3) 有损压缩图像

 # assuming you already have the PIL Image object (im)
 quality_val = 90
 new_img_file = BytesIO()
 im.save(filename, 'JPEG', quality=quality_val)
 image_size = new_img_file.tell()
 # if image size is too large, keep repeating

客户端

真的,客户端只会让用户的事情变得更简单。您可以尝试在客户端实现这些东西,但如果您依赖它,总是有可能有人绕过您的客户端设置并上传 10TB 大小的“图像”(有些人只是想看着世界燃烧)。

1) 调整大小或压缩 - 与上述相同,但使用 javascript 或 Jquery。

2) 裁剪 - JCrop 是我以前使用过的库。这需要一些工作,但它很有用。您可以帮助用户将图像裁剪为更合适的尺寸,并让他们对图像在新分辨率下的外观有更大的控制权。

2) 有用信息 - 如果用户上传的图片太大,请告知他们。

来源

How to get image size in python-pillow after resize?

How do I resize an image using PIL and maintain its aspect ratio?

How to adjust the quality of a resized image in Python Imaging Library?

【讨论】:

非常感谢您的解释,真的很有帮助。检查第一点MAX_UPLOAD_SIZE = "1048576"MAX_UPLOAD_SIZE = 1048576 不起作用我仍然可以上传1mb 的更大图像。 我很快就给出了这个建议。让我做一些改变。 1.12 MB。再多一点 我更新了我的答案。 限制文件大小下的新信息现在应该更有帮助。 感谢您提供的所有信息。

以上是关于设置图像大小限制并根据需要调整图像大小的主要内容,如果未能解决你的问题,请参考以下文章

AutoLayout 以 50% 比例调整图像大小

为啥 flexbox 项目图像根据其初始大小调整大小不同?

如何调整自定义 UIButton 的图像大小?

根据来自服务器的图像调整imageview大小,然后调整其他标签

根据 UILabel 文本和图像自动调整单元格大小,例如聊天

使用“Vstack”将图像大小调整为屏幕宽度,同时保持纵横比