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