在django中上传到s3之前如何压缩图像?

时间:2018-09-05 11:23:49

标签: python django python-3.x amazon-s3 django-views

我正在开发一个用户可以上传图像的应用程序。我想将图像大小减小200-500kb。 这是我的models.py文件

class Report_item(models.Model):
    owner = models.ForeignKey(settings.AUTH_USER_MODEL)
    title = models.CharField(max_length=255, help_text='*Title for the post e.g. item identity')
    image = models.ImageField(default="add Item image",
                          upload_to=get_uplaod_file_name)


    def __str__(self):
        return self.title + "      " + str(self.publish)

这是我的views.py文件

class ReportCreate(generic.CreateView):
model = Report_item
fields = ['title','image']

def get_form(self, form_class=None):
    if form_class is None:
        form_class = self.get_form_class()
    form = super(ReportCreate, self).get_form(form_class)
    form.fields['title'].widget = TextInput(
        attrs={'placeholder': '*Enter UID e.g. CBSE Marksheet Roll nunber 0506***'})
    return form

def form_valid(self, form):
    self.object = form.save(commit=False)
    self.object.owner = self.request.user
    self.object.save()
    return FormMixin.form_valid(self, form)

我正在使用Django 1.11和S3存储。请在上传到s3之前帮助我压缩图像。

3 个答案:

答案 0 :(得分:1)

因此,我们需要在模型中定义保存方法,以便在保存之前压缩图像。以下代码可帮助我解决问题。

class Report_item(models.Model):
    owner = models.ForeignKey(settings.AUTH_USER_MODEL)
    title = models.CharField(max_length=255, help_text='*Title for the post e.g. item identity')
    
    image = models.ImageField(default="add Item image",
                              upload_to=get_uplaod_file_name)

    def save(self):
        # Opening the uploaded image
        im = Image.open(self.image)

        output = BytesIO()

        # Resize/modify the image
        im = im.resize((100, 100))

        # after modifications, save it to the output
        im.save(output, format='JPEG', quality=90)
        output.seek(0)

        # change the imagefield value to be the newley modifed image value
        self.image = InMemoryUploadedFile(output, 'ImageField', "%s.jpg" % self.image.name.split('.')[0], 'image/jpeg',
                                        sys.getsizeof(output), None)

        super(Report_item, self).save()

借助此5 Mb图像压缩到大约4 kb。

答案 1 :(得分:1)

@ jitesh2796,要保留高宽比,请修改接受的答案以包括以下内容:

def save(self):
       ...
       original_width, original_height = im.size
       aspect_ratio = round(original_width / original_height)
       desired_height = 100  # Edit to add your desired height in pixels
       desired_width = desired_height * aspect_ratio

        # Resize the image
        im = im.resize((desired_width, desired_height))
        ...

请注意,您可能还需要使用round()来确保纵横比是整数。

答案 2 :(得分:0)

假设您要在调整大小后上载图像。您可以使用下面的代码,只需传递图像对象,您将获得调整大小的图像作为回报。

def GetThumbnail(f):
    try:
        name = str(f).split('.')[0]
        image = Image.open(f)
        image.thumbnail((400, 400), Image.ANTIALIAS)
        thumbnail = BytesIO()
        # Default quality is quality=75
        image.save(thumbnail, format='JPEG', quality=50)
        thumbnail.seek(0)
        newImage = InMemoryUploadedFile(thumbnail,
                                   None,
                                   name + ".jpg",
                                   'image/jpeg',
                                   thumbnail.tell(),
                                   None)
        return newImage
    except Exception as e:
        return e