manipulating images

12 views
Skip to first unread message

Sasha

unread,
Jun 20, 2006, 3:21:28 AM6/20/06
to Django users
Hello,

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!

mwtb

unread,
Jun 20, 2006, 3:52:16 AM6/20/06
to Django users

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

Sasha

unread,
Jun 20, 2006, 4:07:37 AM6/20/06
to Django users
hey damian,

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?

mwtb

unread,
Jun 20, 2006, 4:22:29 AM6/20/06
to Django users

Sasha wrote:
> 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

Phil Powell

unread,
Jun 20, 2006, 4:56:08 AM6/20/06
to django...@googlegroups.com
It might be worth you taking a look at the work done on Thumbnails in
DjangoUtils:

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

kwe

unread,
Jun 21, 2006, 8:38:13 AM6/21/06
to Django users
Request Method: POST
Request URL: http://localhost:8000/admin/photos/photo/add/
Exception Type: TypeError
Exception Value: argument 1 must be string or read-only buffer, not
instance
Exception Location:
/usr/local/lib/python2.4/site-packages/django/db/models/base.py in
_save_FIELD_file, line 339

(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?

mwtb

unread,
Jun 21, 2006, 8:47:56 AM6/21/06
to Django users

kwe wrote:

> 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

Doug Van Horn

unread,
Jun 21, 2006, 2:29:43 PM6/21/06
to Django users
I'm no expert either, but this seems to work for me:

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.

kwe

unread,
Jun 21, 2006, 3:31:43 PM6/21/06
to Django users
thanks, that works great.

Reply all
Reply to author
Forward
0 new messages