Image resizing with django?

前端 未结 12 1575
温柔的废话
温柔的废话 2020-12-23 18:06

I\'m new to Django (and Python) and I have been trying to work out a few things myself, before jumping into using other people\'s apps. I\'m having trouble understanding whe

12条回答
  •  余生分开走
    2020-12-23 18:46

    This is what I use in my models to save a new thumbnail if the uploaded image has changed. It's based of another DjangoSnippet but it I can't remember who wrote the orginal - if you know please add a comment so that I can credit them.

    from PIL import Image
    from django.db import models
    from django.contrib.auth.models import User
    
    import os
    import settings
    
    class Photo_Ex(models.Model):
        user = models.ForeignKey(User, blank=True, null=True)    
        photo = models.ImageField(upload_to='photos')
        thumbnail = models.ImageField(upload_to='profile_thumb', blank=True,
                                  null=True, editable=False)
    
        def save(self, *args, **kwargs):
            size = (256,256)
            if not self.id and not self.photo:
                return
    
            try:
                old_obj = Photo_Ex.objects.get(pk=self.pk)
                old_path = old_obj.photo.path
            except:
                pass
    
            thumb_update = False
            if self.thumbnail:
                try:
                    statinfo1 = os.stat(self.photo.path)
                    statinfo2 = os.stat(self.thumbnail.path)
                    if statinfo1 > statinfo2:
                        thumb_update = True
                except:
                    thumb_update = True
    
            pw = self.photo.width
            ph = self.photo.height
            nw = size[0]
            nh = size[1]
    
            if self.photo and not self.thumbnail or thumb_update:
                # only do this if the image needs resizing
                if (pw, ph) != (nw, nh):
                    filename = str(self.photo.path)
                    image = Image.open(filename)
                    pr = float(pw) / float(ph)
                    nr = float(nw) / float(nh)
    
                    if image.mode not in ('L', 'RGB'):
                        image = image.convert('RGB')
    
                    if pr > nr:
                        # photo aspect is wider than destination ratio
                        tw = int(round(nh * pr))
                        image = image.resize((tw, nh), Image.ANTIALIAS)
                        l = int(round(( tw - nw ) / 2.0))
                        image = image.crop((l, 0, l + nw, nh))
                    elif pr < nr:
                        # photo aspect is taller than destination ratio
                        th = int(round(nw / pr))
                        image = image.resize((nw, th), Image.ANTIALIAS)
                        t = int(round(( th - nh ) / 2.0))
                        image = image.crop((0, t, nw, t + nh))
                    else:
                        # photo aspect matches the destination ratio
                        image = image.resize(size, Image.ANTIALIAS)
    
                image.save(self.get_thumbnail_path())
                (a, b) = os.path.split(self.photo.name)
                self.thumbnail = a + '/thumbs/' + b
                super(Photo_Ex, self).save()
                try:
                    os.remove(old_path)
                    os.remove(self.get_old_thumbnail_path(old_path))
                except:
                    pass
    
        def get_thumbnail_path(self):
            (head, tail) = os.path.split(self.photo.path)
            if not os.path.isdir(head + '/thumbs'):
                os.mkdir(head + '/thumbs')
            return head + '/thumbs/' + tail
    
        def get_old_thumbnail_path(self, old_photo_path):
            (head, tail) = os.path.split(old_photo_path)
            return head + '/thumbs/' + tail   
    

提交回复
热议问题