In my app In the save method I am compressing uploaded images. Now I want to also resize the images if they are very large. I played around with PIL in a test environment and came up with this code that works as expected.
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')
However when I try to merge it into my django project I get this error
'int' object is not subscriptable - i = i[0]//2, i[1]//2 # new size
If i understand the error correctly it is because i am passing an int as an array, I dont really understand that because if i try and pass say 2
instead of i
i get the same error. I tried to just resize the image and skip the compression but I was still getting the same error
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
Starting code
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)
CodePudding user response:
I can't test it but you use two different object.
In first code you work all time with PIL.Image()
and its size
gives (width,height)
but in second code you works with File()
and its size
gives number of bytes in file (single number), not (width,height)
(two numbers.
You have to first resize PIL.Image
and later convert it to File()
Something like this (but I can't test it)
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