简体   繁体   中英

How to rotate image before save in Django?

Now I'm creating a web app which allows user to upload images using Django Rest Framework. I'd like to rotate those images according to EXIF tag and save.

At first, I found this way , and it works in local environment. But, now I use Amazon S3 for deployment, then this way doesn't work.

So, I'm trying to rotate image before save and struggling... Recent code is below, raising TypeError at /api/work/ 'str' object is not callable when I post new Work object.

How to fix it?
Or is there other nice way?

[models.py]

from django.db import models
from django.conf import settings
from PIL import Image as Img
from PIL import ExifTags
from io import BytesIO
from django.core.files import File
import datetime


class Work(models.Model):
    owner       = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True)
    title       = models.CharField(max_length=120)
    made_date   = models.DateField(default=datetime.date.today, null=True, blank=True)
    note        = models.TextField(max_length=2000, null=True, blank=True)
    image       = models.ImageField(upload_to='work_pic', default='default_image.png')

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        if self.image:
            pilImage = Img.open(BytesIO(self.image.read()))
            for orientation in ExifTags.TAGS.keys():
                if ExifTags.TAGS[orientation] == 'Orientation':
                    break
            exif = dict(pilImage._getexif().items())

            if exif[orientation] == 3:
                pilImage = pilImage.rotate(180, expand=True)
            elif exif[orientation] == 6:
                pilImage = pilImage.rotate(270, expand=True)
            elif exif[orientation] == 8:
                pilImage = pilImage.rotate(90, expand=True)

            output = BytesIO()
            pilImage.save(output, format='JPEG', quality=75)
            output.seek(0)
            self.image = File(output, self.image.name())

        return super(Work, self).save(*args, **kwargs)

[serializers.py]

from rest_framework import serializers
from .models import Work


class WorkSerializer(serializers.ModelSerializer):
    owner = serializers.HiddenField(default=serializers.CurrentUserDefault())

    class Meta:
        model = Work
        fields = '__all__'

    def create(self, validated_data):
        return Work.objects.create(**validated_data)

In your save() method, you are calling the self.image.name attribute as a function. the Image.name is a string attribute, so you don't have to call it as a function.

So change the line self.image = File(output, self.image.name()) to
self.image = File(output, self.image.name)
will solve the error

Complete Model definition

class Work(models.Model):
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True, blank=True)
    title = models.CharField(max_length=120)
    made_date = models.DateField(default=datetime.date.today, null=True, blank=True)
    note = models.TextField(max_length=2000, null=True, blank=True)
    image = models.ImageField(upload_to='work_pic', default='default_image.png')

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        if self.image:
            pilImage = Img.open(BytesIO(self.image.read()))
            for orientation in ExifTags.TAGS.keys():
                if ExifTags.TAGS[orientation] == 'Orientation':
                    break
            exif = dict(pilImage._getexif().items())

            if exif[orientation] == 3:
                pilImage = pilImage.rotate(180, expand=True)
            elif exif[orientation] == 6:
                pilImage = pilImage.rotate(270, expand=True)
            elif exif[orientation] == 8:
                pilImage = pilImage.rotate(90, expand=True)

            output = BytesIO()
            pilImage.save(output, format='JPEG', quality=75)
            output.seek(0)
            

        return super(Work, self).save(*args, **kwargs)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM