Django - изменение размера изображений с помощью pil

В моем приложении в методе сохранения я сжимаю загруженные изображения. Теперь я хочу также изменить размер изображений, если они очень большие. Я поиграл с PIL в тестовой среде и придумал следующий код, который работает как ожидалось.

from PIL import Image
image = Image.open('img.jpg')

(w,h) = image.size
if (w > 2000):
    i = image.size   # current size (height,width)
    i = i[0]//2, i[1]//2  # new size
    image = image.resize(i, Image.ANTIALIAS)
    image.save('halfresizesssd.jpg')

Однако, когда я пытаюсь объединить его с моим проектом django, я получаю эту ошибку

'int' object is not subscriptable - i = i[0]//2, i[1]//2 # new size

Если я правильно понимаю ошибку, это потому, что я передаю int как массив, я не совсем понимаю это, потому что если я пытаюсь передать, скажем, 2 вместо i, я получаю ту же ошибку. Я пытался просто изменить размер изображения и пропустить сжатие, но все равно получал ту же ошибку

def compress(image):
    im = Image.open(image)
    # create a BytesIO object
    im_io = BytesIO() 
    #resize image
    im = im.convert("RGB")
    im = im.save(im_io,'JPEG', quality=70, optimize=True) 
    # create a django-friendly Files object
    new_image = File(im_io, name=image.name)

    w = new_image.size
    if (w > 1000):
        i = new_image.size   # current size (height,width)
        i = i[0]//2, i[1]//2  # new size
        new_image = new_image.resize(i, Image.ANTIALIAS)

    return new_image

Начальный код

def compress(image):
                im = Image.open(image)
                # create a BytesIO object
                im_io = BytesIO() 
                #resize image
                im = im.convert("RGB")
                im = im.save(im_io,'JPEG', quality=70, optimize=True) 
                # create a django-friendly Files object
                new_image = File(im_io, name=image.name)
                return new_image

class Post(models.Model):
    ....
    image = models.ImageField(storage=PublicMediaStorage(), upload_to=path_and_rename, validators=[validate_image])

def save(self, *args, **kwargs): 
    self.slug = slugify(self.title)

    if self.image:
        # call the compress function
        new_image = compress(self.image)
        # set self.image to new_image
        self.image = new_image

    super(Post,self).save(*args, **kwargs)

Я не могу проверить это, но вы используете два разных объекта.

В первом коде вы все время работаете с PIL.Image() и его size дает (width,height), но во втором коде вы работаете с File() и его size дает количество байт в файле (одно число), а не (width,height) (два числа.

).

Вы должны сначала изменить размер PIL.Image, а затем преобразовать его в File()

Что-то вроде этого (но я не могу это проверить)

def compress(image):
    
    # --- resize ---
    
    img = Image.open(image)
    img = img.convert("RGB")

    (w, h) = img.size   # current size (width, height)

    if w > 1000:
        new_size = (w//2, h//2)  # new size
        img = img.resize(new_size, Image.ANTIALIAS)
    
    # --- convert to File ---

    im_io = BytesIO() 
    img.save(im_io, 'JPEG', quality=70, optimize=True) 

    new_image = File(im_io, name=image.name)

    return new_image
Вернуться на верх