Hi Philip, I'm cc'ing the list, perhaps someone has some input... comments interleaved.
From: Philip Aylesworth <phila@purpleduck.com> Date: Thu, 23 Aug 2001 20:36:13 -0400 (EDT) To: info@bowery.com Subject: image hot fix
Hi Marc,
I have to tell you that this image hot fix is exactly what I need! I was using Photo but it is no longer supported and this does things more the way I want to.
I am modifying it so that it will have several default sizes that can be cached.
Actually, if you look at the code, i *think* I have stuff in there to allow you to use it with a RAMCache. The idea being, make a RAM cache for caching all thumbnail images, not just private caching for each instance. I'm still unfamiliar with how that all works in Zope, but architecturally I think that's the best place to put a cache (external to the images themselves). I still don't see how to get this caching to work for all instances, it seems the caches need to add one instance at a time... But this way, they are stored where appropriate (cached), but not stored inside the image (which could lead to unneccessary data.fs bloat).
I am not to swift with python yet so I just went in and duplicated the thumb method and made some methods called "preview", "small", and "medium"giving them default sizes of 160X120, 320X 240, and 640X480.
The way I have it working, if you call tag() with the same size twice, at the least, the client browser should use the locally cached version (at least, it did for me), so I don't see that it's necessary to have specially named methods. For example, in my CMFPhoto and in the original ZPhoto, the thumbnail pages always call tag with a size of 80, so they'll be cached (at least per client) the second time around.
I have this working now but I noticed one little bug in your code. The "keys =" line reverses the height and width. I fixed this by replacing it with:
keys = {'width':int(width or height), 'height':int(height or width)}
Doh! Thanks for pointing it out! I guess that gives me a reason for version 0.2 (along with changing the name to image HotPatch!) -- though I'm hoping to figure out the RAMCache situation (help! somebody!) first...
Now I have one question, if you don't mind. How do I make the tag method return a URL for the size of image that I want? I see that you have thumb hard coded in there. If you have time to take a look at this I would really appreciate it.
I have thumb hard coded (in tag), because that's the method the browser will then call (with arguments) to actually fetch the image. I guess, if you're rolling with the three special method approach (though I don't think it's necessary), then in tag I guess you'd either create a new parameter for tag (size=[preview,small,medium]) or match one of the three names with a range of sizes, and put more if/elses in there to return the right one.
Thanks for the great work!
Phil.
Philip Aylesworth phila@purpleduck.com
Marc I've tested your hotfix and it does work great at allowing the use of PIL with the standard image tag method. However, because without the use of caching the rendering of a simple thumbnail page may become a real pain, (the thumbnails will always regenerate from the original images, over a over again every time the page is loaded), it would be really helpful that you provide a how-to/readme on the subject of the use of RAMCache along with your product. On the other hand I'd like to point out that PIL - although it's a familiar Python native library to work with- has serious lacks of image quality after resampling. The jaggy look of thumbnails is unpleasant for a professional site. Why is that? I've tested the three available methods (nearest, bilinear and bicubic), with a large-size image (2000 X 1500 or so) finding that at a thumbnail level all the samples looked the same. And bicubic is the best known (and costly) resample method. A search at the Image-sig archives also reveals the problem, apparently leading to the use of GIMP with a Python interface -instead of PIL-, when quality becomes a concern. Has anyone found a workaround for the jaggy look of PIL's resized images in Zope? Ausum ----- Original Message ----- From: "marc lindahl" <marc@bowery.com> To: "Philip Aylesworth" <phila@purpleduck.com>
Hi Philip, I'm cc'ing the list, perhaps someone has some input... comments interleaved.
From: Philip Aylesworth <phila@purpleduck.com> Date: Thu, 23 Aug 2001 20:36:13 -0400 (EDT) To: info@bowery.com Subject: image hot fix
Hi Marc,
I have to tell you that this image hot fix is exactly what I need! I was using Photo but it is no longer supported and this does things more the way I want to.
I am modifying it so that it will have several default sizes that can be cached.
Actually, if you look at the code, i *think* I have stuff in there to allow you to use it with a RAMCache. The idea being, make a RAM cache for caching all thumbnail images, not just private caching for each instance. I'm still unfamiliar with how that all works in Zope, but architecturally I think that's the best place to put a cache (external to the images themselves). I still don't see how to get this caching to work for all instances, it seems the caches need to add one instance at a time...
But this way, they are stored where appropriate (cached), but not stored inside the image (which could lead to unneccessary data.fs bloat).
I am not to swift with python yet so I just went in and duplicated the thumb method and made some methods called "preview", "small", and "medium"giving them default sizes of 160X120, 320X 240, and 640X480.
The way I have it working, if you call tag() with the same size twice, at the least, the client browser should use the locally cached version (at least, it did for me), so I don't see that it's necessary to have specially named methods. For example, in my CMFPhoto and in the original ZPhoto, the thumbnail pages always call tag with a size of 80, so they'll be cached (at least per client) the second time around.
I have this working now but I noticed one little bug in your code. The "keys =" line reverses the height and width. I fixed this by replacing it with:
keys = {'width':int(width or height), 'height':int(height or width)}
Doh! Thanks for pointing it out! I guess that gives me a reason for version 0.2 (along with changing the name to image HotPatch!) -- though I'm hoping to figure out the RAMCache situation (help! somebody!) first...
Now I have one question, if you don't mind. How do I make the tag method return a URL for the size of image that I want? I see that you have thumb hard
coded
in there. If you have time to take a look at this I would really appreciate it.
I have thumb hard coded (in tag), because that's the method the browser will then call (with arguments) to actually fetch the image.
I guess, if you're rolling with the three special method approach (though I don't think it's necessary), then in tag I guess you'd either create a new parameter for tag (size=[preview,small,medium]) or match one of the three names with a range of sizes, and put more if/elses in there to return the right one.
Thanks for the great work!
Phil.
Philip Aylesworth phila@purpleduck.com
On Mon, 27 Aug 2001, Ausum wrote:
On the other hand I'd like to point out that PIL - although it's a familiar Python native library to work with- has serious lacks of image quality after resampling. The jaggy look of thumbnails is unpleasant for a professional site. Why is that? I've tested the three available methods (nearest, bilinear and bicubic), with a large-size image (2000 X 1500 or so) finding that at a thumbnail level all the samples looked the same. And bicubic is the best known (and costly) resample method. A search at the Image-sig archives also reveals the problem, apparently leading to the use of GIMP with a Python interface -instead of PIL-, when quality becomes a concern.
Has anyone found a workaround for the jaggy look of PIL's resized images in Zope?
Nothing to do with Zope (yet), but I've written a specific web site generator in Python for the online atlas of neurooncology of the ANOCEF with a lot of pictures taken from a slide scanner (Epson filmscan 200) and automatically resized to three different sizes (http://anocef.unice.fr/atlasneuro/) using ImageMagick. This pictures really HAVE to be clean and nice even at thumbnail size, and according to all the professionals and specialists involved they are very good. So maybe you could give a look at ImageMagick, especially the "mogrify" command. I've used it only from os.system, but AFAIK there's a python module for ImageMagick which may produce better results than PIL (untested), it's called PyMagick IIRC. hoping this helps. bye, Jerome Alet - alet@unice.fr - http://cortex.unice.fr/~jerome Fac de Medecine de Nice http://wwwmed.unice.fr Tel: (+33) 4 93 37 76 30 Fax: (+33) 4 93 53 15 15 28 Avenue de Valombrose - 06107 NICE Cedex 2 - FRANCE
From: Jerome Alet <alet@unice.fr>
So maybe you could give a look at ImageMagick, especially the "mogrify" command. I've used it only from os.system, but AFAIK there's a python module for ImageMagick which may produce better results than PIL (untested), it's called PyMagick IIRC.
I had a look at ImageMagick, and decided it's not exactly Python friendly. Both packages are kind of a pain to install, but ImageMagick does seem a little more widely available as an easy-to-install RPM. PyMagick has basically disappeared from the web... I found a copy of it, but obviously old, and unsupported. That's why I went with PIL.
* Jerome Alet <alet@unice.fr> [010827 16:06]:
On Mon, 27 Aug 2001, Ausum wrote:
Has anyone found a workaround for the jaggy look of PIL's resized images in Zope?
So maybe you could give a look at ImageMagick, especially the "mogrify" command. I've used it only from os.system, but AFAIK there's a python module for ImageMagick which may produce better results than PIL (untested), it's called PyMagick IIRC.
I too use ImageMagick. Its quality is excellent, and it handles a huge variety of image formats (e.g. PSDs, PhotoCD...). You'll have a hard time tracking down PyMagick. However, as Shane has pointed out, is there a compelling reason for using python wrappers around native code anyway? If you use popen2 or similar modules, you get to start the conversion in a separate process, and connect to its input/output/error streams using pipes. With (potentially) intensive processes like thumbnailing a Photoshop image of unknown size, aren't you better off doing it in a separate process anyway? You could even farm off conversion routines to a separate box. seb
I too use ImageMagick. Its quality is excellent, and it handles a huge variety of image formats (e.g. PSDs, PhotoCD...).
You'll have a hard time tracking down PyMagick. However, as Shane has pointed out, is there a compelling reason for using python wrappers around native code anyway? If you use popen2 or similar modules, you get to start the conversion in a separate process, and connect to its input/output/error streams using pipes. With (potentially) intensive processes like thumbnailing a Photoshop image of unknown size, aren't you better off doing it in a separate process anyway? You could even farm off conversion routines to a separate box.
If you want to get really whacky, I happily used a python wrapper, by using pyperl around the perl one. Worked fine for me and the perl module is more complete than than the python one, performance was probably not the best though :) Cheers. -- Andy McKay.
From: seb bacon <seb@jamkit.com>
You'll have a hard time tracking down PyMagick. However, as Shane has pointed out, is there a compelling reason for using python wrappers around native code anyway? If you use popen2 or similar modules, you get to start the conversion in a separate process, and connect to its input/output/error streams using pipes.
Yikes! The invitation's open for anyone to modify the product to use ImageMagick in this way (just don't call it a hot fix :))
With (potentially) intensive processes like thumbnailing a Photoshop image of unknown size, aren't you better off doing it in a separate process anyway?
If that's the paramter... for me, I don't see my site ever having images that large, since they're mostly uploaded by users TTW, and otherwise the highest quality would be for commercial magazine print, so we only need maybe 300 dpi.
You could even farm off conversion routines to a separate box.
for a really huge site, sure! You'd have to look a the statistics of expect amount and variation of thumbnails, etc. -- perhaps one of the other approaches, like storing the thumbs in the image object, or manually creating and storing thumbs, might be appropriate in those cases... depends on alot of factors.
Seb, would you mind to share with us the main guidelines for an ImageMagick-Zope implementation like yours? :) I think you're right on the subject of setting up separate processes. I'd use Photoshop if there was a straight method to Photoshop from Zope and viceversa, in Windows. But there's not, and at this very moment it's neccesary to deal with OLE automation controllers, prior to any Zope acquaintance. Although the farm idea is perfectly suited for an intense image-processing environment, I prefer to store new image sizes (like in ZPhoto and Photo) and only process once for every new image. I think that Marc's ImageTag hotfix and Photo/ZPhoto products might need to be merged in the standard image object: A standard image may or not contain its own other resized versions, as a user's choice, AND a standard image's tag methods should be able to custom-resize it on the fly, using PIL (in the medium term I expect PIL to workout its quality issues). What does the list think about this? :) Ausum Seb wrote:
I too use ImageMagick. Its quality is excellent, and it handles a huge variety of image formats (e.g. PSDs, PhotoCD...).
You'll have a hard time tracking down PyMagick. However, as Shane has pointed out, is there a compelling reason for using python wrappers around native code anyway? If you use popen2 or similar modules, you get to start the conversion in a separate process, and connect to its input/output/error streams using pipes. With (potentially) intensive processes like thumbnailing a Photoshop image of unknown size, aren't you better off doing it in a separate process anyway? You could even farm off conversion routines to a separate box.
seb
From: "Ausum" <augusto@artlover.com>
I prefer to store new image sizes (like in ZPhoto and Photo) and only process once for every new image.
The problem I have with that is the potential data.fs bloat. But if you did it only on upload, that would be a solution...
I think that Marc's ImageTag hotfix and Photo/ZPhoto products might need to be merged in the standard image object: A standard image may or not contain its own other resized versions, as a user's choice, AND a standard image's tag methods should be able to custom-resize it on the fly, using PIL (in the medium term I expect PIL to workout its quality issues).
What does the list think about this? :)
Problem I have with that is, if you don't care about the dynamic resizing, then why muck with PIL? THat's why, I think it's good to make it a 'monkey patch' that can either be installed or not... So perhaps your 'uber-image' package could allow features to be enabled or disabled - so if you don't have PIL installed, it doesn't cause an error if it's disabled.
-----Original Message----- From: zope-admin@zope.org [mailto:zope-admin@zope.org]On Behalf Of
So maybe you could give a look at ImageMagick, especially the "mogrify" command. I've used it only from os.system, but AFAIK there's a python module for ImageMagick which may produce better results than PIL (untested), it's called PyMagick IIRC.
I've been running some tests with my Photo product that uses PIL and comparing it to the output of mogrify and I can barely tell any difference in any of the rendered images. I've resized 1024x768 JPG to 480x'whatever' and 128x'whatever' and I don't see enough difference to say ImageMagick is better. In fact, parts of the image seem better with PIL and other parts with IM. Am I missing something? What options should I be using for mogrify? If people are disatisfied with PIL resizes, I'd like to provide an alternative, but IM isn't nearly as Python friendly. _______________________ Ron Bickers Logic Etc, Inc.
On Mon, 27 Aug 2001, Ron Bickers wrote:
-----Original Message----- From: zope-admin@zope.org [mailto:zope-admin@zope.org]On Behalf Of
So maybe you could give a look at ImageMagick, especially the "mogrify" command. I've used it only from os.system, but AFAIK there's a python module for ImageMagick which may produce better results than PIL (untested), it's called PyMagick IIRC.
I've been running some tests with my Photo product that uses PIL and comparing it to the output of mogrify and I can barely tell any difference in any of the rendered images. I've resized 1024x768 JPG to 480x'whatever' and 128x'whatever' and I don't see enough difference to say ImageMagick is better. In fact, parts of the image seem better with PIL and other parts with IM. Am I missing something? What options should I be using for mogrify?
You can at least play with the "-quality" option, e.g. "-quality 100" will produce the best output in jpeg, and beware that the default value is 75, not 100. However I didn't say that IM's output is better than PIL's one, just that maybe you could try and test it. while not being as python friendly as PIL is, ImageMagick is a lot more than PIL, it's a complete toolbox, not just an API. I happily use both in different software I've written and am satisfied with both. bye, Jerome Alet
-----Original Message----- From: zope-admin@zope.org [mailto:zope-admin@zope.org]On Behalf Of Jerome Alet
You can at least play with the "-quality" option, e.g. "-quality 100" will produce the best output in jpeg, and beware that the default value is 75, not 100.
I'll play with that some. Thanks.
However I didn't say that IM's output is better than PIL's one, just that maybe you could try and test it.
I've read in more than one place on and off this list that suggested IM made much better resized images. I'm just trying to reproduce it and compare the output before I spend time making it work with Photo.
while not being as python friendly as PIL is, ImageMagick is a lot more than PIL, it's a complete toolbox, not just an API.
Agreed. I wish the python module were up to date. I only need resizing anyway, so even PIL is much more than required. _______________________ Ron Bickers Logic Etc, Inc.
From: "Ron Bickers" <rbickers-dated-999612534.2a1697@logicetc.com>
I've read in more than one place on and off this list that suggested IM made much better resized images. I'm just trying to reproduce it and compare the output before I spend time making it work with Photo.
I wonder, though, if it's just comparint PIL's "thumbnail" command. According to the manual, that resizes the image in draft mode, which uses no special interpolation. To resize otherwise takes slightly more work, and different commands.
-----Original Message----- From: zope-admin@zope.org [mailto:zope-admin@zope.org]On Behalf Of marc lindahl
I wonder, though, if it's just comparint PIL's "thumbnail" command. According to the manual, that resizes the image in draft mode, which uses no special interpolation. To resize otherwise takes slightly more work, and different commands.
I'm using PIL.resize and it's clearly not as good as IM's output. I just realized, however, that IM is very slow compared to PIL when it comes to resizing. With Photo, it takes 20 seconds to resize an 800k image to 5 different display sizes using 'mogrify'. It takes PIL 5 seconds. 'mogrify' from the command line proves just as slow. Sigh. _______________________ Ron Bickers Logic Etc, Inc.
-----Original Message----- From: marc lindahl [mailto:marc@bowery.com]
I'm using PIL.resize and it's clearly not as good as IM's output.
Are you using it with NEAREST, BILINEAR, or BICUBIC (filter param)?
I've tried all three. The results are pretty much the same. _______________________ Ron Bickers Logic Etc, Inc.
* Ron Bickers <rbickers-dated-999542769.b3b605@logicetc.com> [010827 19:55]:
So maybe you could give a look at ImageMagick, especially the "mogrify" command. I've used it only from os.system, but AFAIK there's a python module for ImageMagick which may produce better results than PIL (untested), it's called PyMagick IIRC.
I've been running some tests with my Photo product that uses PIL and comparing it to the output of mogrify and I can barely tell any difference in any of the rendered images. I've resized 1024x768 JPG to 480x'whatever' and 128x'whatever' and I don't see enough difference to say ImageMagick is better. In fact, parts of the image seem better with PIL and other parts with IM. Am I missing something? What options should I be using for mogrify?
I'm afraid I just don't have time to gather the evidence right now, but unless I've made some huge mistake, there are definitely problems with the PIL resizing output quality - I've seen 'jagged edges' too. The tests you mention are scaling images by powers of two (i.e. 480 = 1024 / 2, 128 = 1024 / 2^3) which will minimise the number of rounding errors (I'm guessing a bit - can you tell? ;-). Have you tried scaling down by 1/3, 1/7, etc?
If people are disatisfied with PIL resizes, I'd like to provide an alternative, but IM isn't nearly as Python friendly.
I'm still not clear of the _disadvantage_ of having to do an os.popen() call, or similar? cheers, seb
* seb bacon <seb@jamkit.com> [010828 10:34]:
The tests you mention are scaling images by powers of two (i.e. 480 = 1024 / 2, 128 = 1024 / 2^3) which will minimise the number of rounding errors (I'm guessing a bit - can you tell? ;-). Have you tried scaling down by 1/3, 1/7, etc?
*cough* my thesis is proved entirely wrong by my inability to divide 1024 by 2. I guess that doesn't lend credibility to my assertion that PIL makes jagged images, either. Oh well ;-) seb
For those willing to run a test by themselves, here I've uploaded the perfect image for a testing purpose: http://www.zope.org/Members/ausum/testfolder/catamaran.jpg Don't forget to tell what you have found. :) Ausum Ron Bickers wrote:
-----Original Message----- From: zope-admin@zope.org [mailto:zope-admin@zope.org]On Behalf Of
So maybe you could give a look at ImageMagick, especially the "mogrify" command. I've used it only from os.system, but AFAIK there's a python module for ImageMagick which may produce better results than PIL (untested), it's called PyMagick IIRC.
I've been running some tests with my Photo product that uses PIL and comparing it to the output of mogrify and I can barely tell any difference in any of the rendered images. I've resized 1024x768 JPG to 480x'whatever' and 128x'whatever' and I don't see enough difference to say ImageMagick is better. In fact, parts of the image seem better with PIL and other parts with IM. Am I missing something? What options should I be using for mogrify?
If people are disatisfied with PIL resizes, I'd like to provide an alternative, but IM isn't nearly as Python friendly. _______________________
Ron Bickers Logic Etc, Inc.
-----Original Message----- From: Ausum [mailto:augusto@artlover.com]
For those willing to run a test by themselves, here I've uploaded the perfect image for a testing purpose:
http://www.zope.org/Members/ausum/testfolder/catamaran.jpg
Don't forget to tell what you have found. :)
Well. It seems that IM does produce much smoother images without jagged edges, though the smallest ones appear slighly blurry to me. I think I'll see about making it an option in Photo. Any suggestions on whether to bother with the clearly old PyMagick module or just to try running mogrify? _______________________ Ron Bickers Logic Etc, Inc.
From: "Ausum" <augusto@artlover.com>
However, because without the use of caching the rendering of a simple thumbnail page may become a real pain, (the thumbnails will always regenerate from the original images, over a over again every time the page is loaded), it would be really helpful that you provide a how-to/readme on the subject of the use of RAMCache along with your product.
I will as soon as I figure out how that stuff works!!! I put in code, looking at the tiny bit of examples on the cache API, but I can't find any other doc or anything explaining how this stuff works, so I'm a little stuck myself. Without the RAMCache set up, the thumbs will be regenerated for every different client - but I did set up the headers so that each client's browser will cache the thumbs locally.
On the other hand I'd like to point out that PIL - although it's a familiar Python native library to work with- has serious lacks of image quality after resampling. The jaggy look of thumbnails is unpleasant for a professional site. Why is that? I've tested the three available methods (nearest, bilinear and bicubic), with a large-size image (2000 X 1500 or so) finding that at a thumbnail level all the samples looked the same. And bicubic is the best known (and costly) resample method. A search at the Image-sig archives also reveals the problem, apparently leading to the use of GIMP with a Python interface -instead of PIL-, when quality becomes a concern.
Actually, looking at PIL's doc's - the thumbnail command (which I'm using) calls the 'draft' command which doesn't have any interpolation. Possibly by using different commands in PIL you can get interpolation.
participants (10)
-
Andy McKay -
Ausum -
Jerome Alet -
marc lindahl -
Ron Bickers -
Ron Bickers -
Ron Bickers -
Ron Bickers -
Ron Bickers -
seb bacon