在保存到python Django模型中之前如何调整ImageField图像的大小

时间:2019-07-19 11:31:55

标签: python django

我正在尝试实现Django ImageField类函数来调整图像大小,但是我不确定该函数在哪里接受我的新图像尺寸

在Linux和Python 3.7上运行

我看过这份文档,但是不太明白: https://docs.djangoproject.com/en/1.11/_modules/django/db/models/fields/files/#ImageField

如果有人可以向我展示如何使用此功能的示例,我将不胜感激。

编辑

我还没有成功调整图像尺寸的大小,这就是我想要达到的目的。鉴于ImageField正在抓取图像,我该如何调整图像的大小(我发现update_dimensions_fields的{​​{1}}类函数,但是我不知道如何使用它)

ImageField

3 个答案:

答案 0 :(得分:2)

**

这将起作用 **首先使用“点子安装枕头”安装“ PIL叉子”

from PIL import Image


def __str__(self):
    return self.title


def save(self, *args, **kwargs):
    super(Posts, self).save(*args, **kwargs)
    imag = Image.open(self.post_image.path)
    if imag.width > 400 or imag.height> 300:
        output_size = (400, 300)
        imag.thumbnail(output_size)
        imag.save(self.post_image.path)
class Meta:
    verbose_name_plural = "Posts"

答案 1 :(得分:1)

您可以使用django-resized库。上传时会调整图像大小并为您存储。

用法

from django_resized import ResizedImageField

class Posts(models.Model):
    title = models.CharField(max_length=200, blank=True)
    body = models.TextField(blank=True)
    created_at = models.DateTimeField(default=datetime.datetime.now)
    post_image = ResizedImageField(size=[500, 300], upload_to=get_image_path, blank=True, null=True)

    def __str__(self):
        return self.title

选项

  • 大小-最大宽度和高度,例如[640,480]
  • 作物-调整大小和裁剪。 ['top','left']-左上角,['middle',- 'center']是中心裁剪,['bottom','right']-裁剪右下角。
  • 质量-调整大小后的图像1..100的质量
  • keep_meta -保留EXIF和其他元数据,默认为True
  • force_format -强制调整大小的图像的格式,可用的格式是枕头支持的格式,默认为无

答案 2 :(得分:0)

您可以使用此方法在保存之前调整图像大小:(您需要pip install pillow

import os
from io import BytesIO
from PIL import Image as PilImage
from django.core.files.base import ContentFile
from django.core.files.uploadedfile import InMemoryUploadedFile, TemporaryUploadedFile

def resize_uploaded_image(image, max_width, max_height):
    size = (max_width, max_height)

    # Uploaded file is in memory
    if isinstance(image, InMemoryUploadedFile):
        memory_image = BytesIO(image.read())
        pil_image = PilImage.open(memory_image)
        img_format = os.path.splitext(image.name)[1][1:].upper()
        img_format = 'JPEG' if img_format == 'JPG' else img_format

        if pil_image.width > max_width or pil_image.height > max_height:
            pil_image.thumbnail(size)

        new_image = BytesIO()
        pil_image.save(new_image, format=img_format)

        new_image = ContentFile(new_image.getvalue())
        return InMemoryUploadedFile(new_image, None, image.name, image.content_type, None, None)

    # Uploaded file is in disk
    elif isinstance(image, TemporaryUploadedFile):
        path = image.temporary_file_path()
        pil_image = PilImage.open(path)

        if pil_image.width > max_width or pil_image.height > max_height:
            pil_image.thumbnail(size)
            pil_image.save(path)
            image.size = os.stat(path).st_size

    return image

然后在你表单中image字段的clean方法中使用:

class ImageForm(forms.Form):
    IMAGE_WIDTH = 450
    IMAGE_HEIGHT = 450
    
    image = forms.ImageField()

    def clean_image(self):
        image = self.cleaned_data.get('image')
        image = resize_uploaded_image(image, self.IMAGE_WIDTH, self.IMAGE_HEIGHT)
        return image

要了解 resize_uploaded_image 方法的工作原理,您可以阅读文档 herehere 中有关 Django 如何处理上传文件的内容。