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
You can give a try to:
image headcut
features:
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:
I also swear by Justin Driscoll's django-photologue is also great for resizing. It:
Basically it's awesome.
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
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.
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.