Image resizing with django?

前端 未结 12 1503
温柔的废话
温柔的废话 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:36

    You can give a try to:

    image headcut

    features:

    • Allows you to set the center of attention of an image... heads won't get cut anymore.
    • Video thumbnailing
    • Prevents cross-site image linking
    • Simple setup and usage
    0 讨论(0)
  • 2020-12-23 18:36

    Another alternative is to use Imagemagick directly, if you want to avoid several difficulties with Pillow and Python 3 such as this one.

    from subprocess import call
    call(['convert', img_path_file_name, '-thumbnail', target_size_str, '-antialias', style_path_file_name])
    

    You could call this on model save, or on a template tag to generate an one-off manipulated copy of the original file in a file-caching fashion, or even a celery task.

    You can get an example of how I have used this in one of my projects:

    • main function
    • relevant settings
    • templatetag
    • how to use
    0 讨论(0)
  • 2020-12-23 18:40

    I also swear by Justin Driscoll's django-photologue is also great for resizing. It:

    1. Resizes (that is can be scaled to a height or width proportionately)
    2. Crops (kind-of intelligently: from the center, top, left, bottom or right)
    3. Optionally upsizes
    4. Can add effects (such as "color", "brightness", "contrast" and "sharpness" as well as filters like "Find Edges" and "Emboss". Sharpen your images. Make your thumbnails black and white.)
    5. Can add simple watermark
    6. Cache the results

    Basically it's awesome.

    0 讨论(0)
  • 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   
    
    0 讨论(0)
  • 2020-12-23 18:47

    I guess it depends on how and when your using your thumbnails.

    If you want to create some thumbnails every time the Country is saved, you could do it like so:

    from django.db import models
    
    # This is to list all the countries
    # For starters though, this will be just United Kingdom (GB)
    class Country(models.Model):
        name = models.CharField(max_length=120, help_text="Full name of country")
        code = models.CharField(max_length=2, help_text="This is the ISO 3166 2-letter country code (see: http://www.theodora.com/country_digraphs.html)")
        flag = models.ImageField(upload_to="images/uploaded/country/", max_length=150, help_text="The flag image of the country.", blank=True)
    
        class Meta:
            verbose_name_plural = "Countries"
    
        def __unicode__(self):
            return self.name
    
        def save(self, force_insert=False, force_update=False):
            resize_image(self.flag)
            super(Country, self).save(force_insert, force_update)
    

    If you aren't 100% sure what sizes you'll need your images, you could resize them last minute. I've seen this effectively done with a templatetag (I believe in a version on Pinax). You create a templatetag that takes the image and a size, then create and save the image of the appropriate size if you need to, or display a previously created one if it's there. It works pretty well.

    0 讨论(0)
  • 2020-12-23 18:49

    Not sure about the code you sent, because I never use Models as such, but there is another method.

    You can implement your own FileUploadHandler for handling image file uploads. Example is here. Just after line 37 (dest.close()) use thumbnail(upload_dir + upload.name) function (the one you sent).

    Hope it helps you.

    0 讨论(0)
提交回复
热议问题