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.