I'd like to create a thumbnail for an image after it has been uploaded.
I have seen two possible approaches descibed here - subclassing
ImageField and overriding the save() method of the model. Although the
former seems more elegant, the latter seems like less work and I'm
inclined to try it first.
However I'm not clear about how I can manipulate an ImageField (or any
field for that matter) inside the models' save() method. Can anyone
help?
Thanks!
Are you wanting to replace the original image with a thumbnail, or do
you want to create another ImageField entry with the thumbnail? I'm
doing the second method.
Perhaps all you need to know is that the ImageField can be saved using
yourmodel.save_yourfieldname_file(), which takes a filename and desired
file contents. Be aware that calling this will trigger a re-save of the
whole model and so you'll need to put some sort of conditional around
it to avoid a recursion.
Damian Sinclair
thanks for replying. i'd like to save the thumbnail into a separate
field. i just found the save_fieldname_file() method using the shell.
so my model looks like this:
class Picture(models.Model):
image = models.ImageField(upload_to="uploads", blank=True)
thumbnail = models.ImageField(upload_to="uploads", blank=True)
title = models.CharField(blank=True, maxlength=200, core=True)
size = models.CharField(blank=True, maxlength=50)
medium = models.CharField(blank=True, maxlength=50)
date = models.CharField(blank=True, maxlength=4)
def __str__(self):
return self.title
def save(self):
super(Picture, self).save()
if self.image and not self.thumbnail:
import Image
myImage = Image.open(self.get_image_filename())
myImage.thumbnail((150,150))
myName = 'th_' + self.get_image_filename().split('/')[-1]
self.save_thumbnail_file(myName, myImage)
does it make sense?
Sasha,
That's very similar to what I do, although I can't be sure that the
details are correct (such as if the get_image_filename() will return a
path that PIL can use or if the PIL Image class can be used directly as
input to the save_FIELD_file() call. In other words, it looks generally
as I do it. If that actually works as is, can you let me know as it's a
bit prettier in places than my code.
That's not to say that someone with more Django and Python expertise
than myself won't come along and tell us to do it differently, and I'd
be glad of some reassurance on the matter myself.
Damian Sinclair
http://djangoutils.python-hosting.com/wiki/Thumbnails
Although not a solid chunk of code (there are a few issues with
namespaces, and it uses some Python 2.4 specific stuff), but with a
bit of hacking I got automatic thumbnail generation working recently,
using template filters.
-Phil
(with above code)
I guess this means "if the PIL Image class can be used directly as
input to the save_FIELD_file() call." - it can't ?
sorry new to python and just want to check I'm reading the error
correctly. Any ideas on how to change the type?
> I guess this means "if the PIL Image class can be used directly as
> input to the save_FIELD_file() call." - it can't ?
>
> sorry new to python and just want to check I'm reading the error
> correctly. Any ideas on how to change the type?
Again, I'm not somewhere I can confirm this, but try saving the image
to a StringIO file and then calling getvalue( ) on the StringIO file to
get the raw data for the save_FIELD_file() call.
Damian Sinclair
fp = StringIO()
myImage.save(fp, 'jpeg') # or whatever format
self.save_thumbnail_file(myName, fp.getvalue())
Nice thread. I was just fixin' to get to this for my demo app.
Thanks!
doug.