I done a cool functionality to my site, the possibility to resize
images on demand. It's not 100% done yet but my goal is to do
something like:
...
class Article(models.Model):
photo = models.ImageField(upload_to='some/path/some/where')
def get_photo_200x200(self):
return self.get_photo_miniature(200, 200)
...
The method self.get_photo_miniature will work like get_photo_url, but
it receives the limits of the image miniature, this method check if
there is a file called some/path/some/where/photo_200x200.jpg
(supposing the image filename is photo.jpg). If this file exists,
returns the proper url to it, if not, it resizes the image and store
on this file to then return the miniature url.
I need PIL to this work, but it works a pretty way. The above is
working for me, but the custom method get_photo_miniature is defined
on my model. I want to know if this is a useful feature, then I can
dig up where to put this to make it generic.
Now that I done, I think I can do it another way, maybe using filters.
As images generally goes in templates, I can do something like:
...
<img src="{{ object.image|thumbnail:"200x200" }}">
...
I think you catch the idea. What do you think?
I sent a post about the problem of the filename being unique, I don't
bother about this anymore, I see that if I put 2 files with same name,
the files start to append a _ on the filename. But I still think the
upload_to keyword could receive id.
Thanks for all help, sorry if I was meaningless.
Please direct questions of this nature to django-users; django-dev is
used to discuss the development of Django itself, not to answer usage
questions.
Thanks!
Jacob
Ok, sorry about that Jacob!
Thanks for pointing me at right place!
Best Regards,
Would you consider adding a thumbnail capability to Django? I know
there are contributions out there that do it and the dependency on PIL
might be a negative but I believe this is a very common use case. How
many apps have an image field and don't use some sort of thumbnail? I
bet very few.
Having a standard integrated in Django would be a big plus IMHO.
-Chrus
I'd be +1 on adding something as a contrib app. I've got some code we
use at work, but it'll likely be some time before I'm able to
generalize it enough for public consumption, so I'd be thrilled to see
an effort by a few committed community members...
Jacob
> I'd be +1 on adding something as a contrib app. I've got some code we
> use at work, but it'll likely be some time before I'm able to
> generalize it enough for public consumption, so I'd be thrilled to see
> an effort by a few committed community members...
I done some code to implement it. Look at the following snippet:
http://www.djangosnippets.org/snippets/192/
I used filters to implement this task, did you like the filter
approach or do you think to have a method like
object.get_image_thumbnail on the model is better? I must confess that
use filter was easier to implement and it's easier to use too, I don't
realize how to specify the limits of the image once I can't send
parameters to the get_image_thumbnail method:
Now the questions (not about usage but about directioning :P):
1) What could be the name of the contrib package? Could it be in
webdesign?
2) What is the better approach? Do a filter or a custom method on the
model?
3) Should I create a ticket?
Best regards!
On the user list I found a more complete solution:
http://code.google.com/p/django-utils/wiki/Thumbnail
Maybe this could be add as a contrib package?
Best regards!
I've got a chunk of code that's reasonably generic but needs some
tidying up and decoupling... it's just a template tag... can be found:
for the main code and:
there for the actual template tag.
It saves the thumbnail to the filesystem when it needs to regenerate it,
and so should even be reasonably fast after the first access.
Thanks,
Brett Parker.
http://code.djangoproject.com/wiki/ThumbNails
-Chris
Please read through the documentation and give some feedback.
However, this feels a little bit clunky:
{% with object.imagefield|thumbnail:"150x100" as thumb %}
<img src="{{ thumb.url }}" width="{{ thumb.thumbnail.size.0 }}"
height="{{ thumb.size.1 }}" />
{% endwith %}
What if we had a shortcut like this:
{{ object.imagefield|thumbnail_full_tag:"150X100" }}
Which would generate:
<img src="source/file" width="150" height="100" />
- Also, one thing that is nice in Nesh's version is that it is easy to
cache thumbnails in memory. I think this would be a nice & fairly
simple thing to add.
Once again, really nice work. I look forward to seeing this in
Django. I think it would be really really useful.
-Chris
> - Big positive in that you documented it so well!
This is usually the way to a submitter's heart. ;)
> - I like the fact that it's simple to create your own thumbnail
> classes if necessary.
> - Squash, crop and thumbnail are all very useful and I think it's
> great to have all these available.
I made crop recently for another project - squash isn't quite so nice
but people may want it ;)
> - This syntax looks just fine:
> <img src="{{ object.imagefield|thumbnail:"150x100" }}" />
>
> However, this feels a little bit clunky:
> {% with object.imagefield|thumbnail:"150x100" as thumb %}
> <img src="{{ thumb.url }}" width="{{ thumb.thumbnail.size.0 }}"
> height="{{ thumb.size.1 }}" />
> {% endwith %}
>
> What if we had a shortcut like this:
> {{ object.imagefield|thumbnail_full_tag:"150X100" }}
I felt a bit hesitant to even add that to documentation - it was more
to show you can access the attributes of the thumbnail object (it's
probably superfluous).
Perhaps it would be better just provide an thumbnail_tag filter to
handle it.
I'd suggest a separate tag to handle it:
{{ object.imagefield|thumbnail_crop:"150X100"|thumbnail_tag }}
> - Also, one thing that is nice in Nesh's version is that it is easy to
> cache thumbnails in memory. I think this would be a nice & fairly
> simple thing to add.
I thought about this, started implementing it and then scrapped the
idea. IMO this is getting in to serving of static files, which
historically Django has tried to steer very clear of.
It wouldn't be difficult to do if it was deemed important enough.
> Once again, really nice work. I look forward to seeing this in
> Django. I think it would be really really useful.
Thanks for the feedback, greatly appreciated. Anyone else (especially
real testing)?
- If we continue to use the format "150x200" to specify the size, we
may want to do a string.lower() on the input. I originally had a
capital X and couldn't figure out what the problem was. Yeah, it's a
stupid mistake on my part but still....
- I'm a little fuzzy on the different methods and how they treat size
constraints. I understand if I set the width and leave height blank,
it should automatically calculate it once the thumb is created. I
would also expect that if I put in both, it's going to scale it and
lose the original aspect ratio.
In other words, I'd like to see some thing like:
picture|thumbnail"width=75"
which would create a picture with the same aspect ratio of width to
height.
If I entered
picture|thumbnail"width=75 height=25"
It should force the image to that size (I think that's what squish
does).
I hope this makes sense. I think the by product of making this
semantic change is that one tag would do thumbnail and crop.
Otherwise it all appeared to work well for me.
Oh yeah, upon thinking more about my comment on caching the image, I
think you're probably right. We should leave that in the category of
serving static media.
-Chris
>
> - I'm a little fuzzy on the different methods and how they treat size
> constraints. I understand if I set the width and leave height blank,
> it should automatically calculate it once the thumb is created. I
> would also expect that if I put in both, it's going to scale it and
> lose the original aspect ratio.
>
> In other words, I'd like to see some thing like:
> picture|thumbnail"width=75"
You can't leave the width or height blank.
"scale" sizes the image down proportionally until it fits inside the
given dimensions so the thumbnail images may differ in their
dimensions (they'll either have the width or height - would you really
want an image to be scaled down to 75px width but still be 10,000px
high?)
"crop" cuts off parts of the image to make it take up exactly the
width and height you specify (but without skewing the image ratio like
"squash" does)
So we can't combine scale and crop, because they do different things.
Original Image 1 = 750 X 100, I would only like to specify that the
new image was 75 wide and let it figure out that the new height should
be 10 (preserve aspect ratio given the new width constraint).
Original Image 2 = 750 X 250, I'd like to convert it to 75 x 25
In other words, I want the width to always be 75 but the height can
vary based on the specifics of the image. Does this make sense? If
this is what I'd like to do, how would I do it with the tag as it
stands now?
-Chris
I test your application and enjoy it SmileyChris, there is just a
bug :), contrib/thumbnails/templatestags/__init__.py is missing, a
"touch __init__.py" solves the problem ;) I like the way you return a
Thumbnail object reather than just the string.
Congratulations, very thanks to you!
Well without specifying a maximum height too, you run the risk of that
75x10,000 image.
Choose a maximum height larger than probable:
<img src="{{ object.imagefield|thumbnail:"75x500" }}" />
Thanks,
Chris
I've been working on adding unit tests for this patch and hit a little
snag regarding the way the "size" is returned.
Say I have an image that is 640x512 and I create a thumbnail passing
in "240x240". The resulting thumbnail is scaled down to "240x192".
Which causes some confusing naming conventions ("retaining 240x240 in
the name) as well as making the height and width return incorrect
values (240 is returned for both the height and width)
I have a couple of ideas of how to fix this but I wanted to pass it by
you first and make sure I'm not off in the wrong direction here. Any
thoughts you'd have on fixing it the simplest way would be
appreciated.
Thanks,
Chris
If you were to call it "240x192" then we wouldn't know that there was
an existing cached thumbnail until we did the hard work of recreating
it to get the dimensions.
Remember those values simply relate to the thumbnail method used, not
the output dimensions.
How were you planning on handling it?
Maybe the filename needs to encode the actual size as well as the
specified size. Something like :
sample_pic_240x240_scale:240x192.jpg
It would make some of the file manipulation a little tricky but would
be more efficient by not calling PIL so much.
The other alternative might be to cache the file sizes and return it
that way. The benfit is that the filenames are cleaner but the
downside might be the complexity.
Or we just keep it the way it is ;)
Is there really that much benefit to having the thumbnail image
filename contain the actual dimensions? If someone cared that much,
they can use PIL (on the thumbnailed image) to find them out.
Sorry, I'm a little late to join this discussion.
We have some code here (at Mercurytide[1]) which we use to generate
thumbnails by cropping and scaling images, results can be seen on the
bottom of the right column of:
<http://www.naelimits.co.uk/activities/stag-hen/>
I'll see what the chances of getting that code if anyone is interested
in this method.
Something we've also found useful is the ability to add "allow_tags"
to a function which generates an <img> tag to display thumbnails in
the admin listing pages, I'm not sure if that's documented, but it was
handy when we found it.
Cheers,
John.
[1] <http://mercurytide.com/>
--
john sutherland
<http://sneeu.com/>
Probably the best thing to do is look at the contrib.thumbnails patch
and see if there's something you could add to it:
http://code.djangoproject.com/ticket/4115
I'm not opposed to modifying the tag to return the actual size by
using PIL calls. It's probably not too big of a performance hit and
if people don't really want to use it they don't have to.
On May 16, 3:58 am, "Chris Beaven" <smileych...@gmail.com> wrote:
On May 17, 1:19 am, "chris.moff...@gmail.com"
I attached a simple patch that shows how I ended up solving the "size"
problem. I just realized there's a small bug in my cut & paste but
you can get the idea.
size_cache.set(self.filename, im.size, _SIZE_CACHE_TIMEOUT)
should be
size_cache.set(self.filename, img.size, _SIZE_CACHE_TIMEOUT)
I think this is a pretty simple solution to what we've discussed.
What do you think?
Also, I took a stab at creating some regression tests. Let me know if
you want to see them.
On May 17, 8:26 pm, SmileyChris <smileych...@gmail.com> wrote:
> Right, check out the ticket again - new patch up.http://code.djangoproject.com/ticket/4115