0

I'm trying to resize a file while the image is uploaded, but I'm have some issue trying to save it into my model's ImageField.

Here is my models.py :

try:
    from PIL import Image, ImageOps
except ImportError:
    import Image
    import ImageOps

class IMGResize(models.Model):
    image = models.ImageField(upload_to='images', blank=True)

    def save(self, *args, **kwargs):
        if self.image:
            img = Image.open(self.image) #<PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=980x490 at 0x59E4B38>

            imageresize = img.resize((200, 200), Image.ANTIALIAS) #<PIL.Image.Image image mode=RGB size=200x200 at 0x4D5F630>
            imageresize.save('newname.jpg', 'JPEG', quality=75) #not being saved here to my models
        super(IMGResize, self).save(*args, **kwargs)

How can I resolve this so I can save the resized image into my model ?

Horai Nuri
  • 5,358
  • 16
  • 75
  • 127

2 Answers2

2

I found the answer on this post by madzohana, which works without any issue.

from PIL import Image
from io import BytesIO
from django.core.files.base import ContentFile

def save(self, *args, **kwargs):
    img = Image.open(self.image)
    resized  = img.resize((200, 200), Image.ANTIALIAS)
    new_image_io = BytesIO()

    if img.format == 'JPEG' :
        resized .save(new_image_io, format='JPEG')
    elif img.format == 'PNG' :
        resized.save(new_image_io, format='PNG')

    temp_name = self.image.name
    self.image.delete(save=False)

    self.image.save(
        temp_name,
        content=ContentFile(new_image_io.getvalue()),
        save=False
    )

    super(IMGResize, self).save(*args, **kwargs)
Community
  • 1
  • 1
Horai Nuri
  • 5,358
  • 16
  • 75
  • 127
1

I believe this will do the trick (edited for PIL Image objects:

from django.core.files.base import ContentFile
import StringIO

....

class IMGResize(models.Model):
    image = models.ImageField(upload_to='images', blank=True)

    def safe(self, *args, **kwargs):
        if self.image:
            img = Image.open(self.image)
            imageresize = img.resize((200, 200), Image.ANTIALIAS)

            image_formatted = Image.open(StringIO(imageresize.content))
            image_io = StringIO()

            image_formatted.save(image_io, format='JPEG')


            self.image.save(self.image.name, ContentFile(image_io.getvalue(), True)

            super(IMGResize, self).save(*args, **kwargs)
dentemm
  • 6,231
  • 3
  • 31
  • 43
  • It gives me this error : 'Image' object has no attribute 'read' – Horai Nuri Apr 13 '17 at 19:23
  • Ah yes you are using a PIL image, wait a minute let me find the correct way for PIL images – dentemm Apr 13 '17 at 19:26
  • I'm interested by the PIL answer, but also with this one, what "Image" library does it use ? – Horai Nuri Apr 13 '17 at 19:31
  • I tried with StringIO once, but it seems like it is compatible with python 3, the problem is that I didn't knew how i could adapt io to work on with the img resize app – Horai Nuri Apr 13 '17 at 19:35
  • I think this should be about right, but it might be possible in a shorter way. My previous example was using sorl.thumbnail for resizing – dentemm Apr 13 '17 at 19:36
  • hmm I see, I had some issues with sorl one the setting up that was the reason why I've changed to PIL – Horai Nuri Apr 13 '17 at 19:37
  • Here you can find my original code for sorl thumbnail: [link](https://github.com/dentemm/tcps/blob/master/tcps/tcps/apps/catalogue/management/commands/resizeimages.py) – dentemm Apr 13 '17 at 19:38
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/141673/discussion-between-dentemm-and-lindow). – dentemm Apr 13 '17 at 19:39
  • I found the answer, if you are interested check the post :) – Horai Nuri Apr 13 '17 at 20:51
  • @HiroyukiNuri I'm interested please show me the answer – Ajay Kumar Mar 06 '20 at 07:24