views:

939

answers:

3

I'm getting about the same bad looking resizing from all the 4 algorithms of PIL

>>> data = utils.fetch("http://wavestock.com/images/beta-icon.gif")
>>> image = Image.open(StringIO.StringIO(data)); image.save("/home/ptarjan/www/tmp/metaward/original.png")
>>>
>>> image = Image.open(StringIO.StringIO(data)); image.resize((36,36), Image.ANTIALIAS).save("/home/ptarjan/www/tmp/metaward/antialias.png")
>>> image = Image.open(StringIO.StringIO(data)); image.resize((36,36), Image.BILINEAR).save("/home/ptarjan/www/tmp/metaward/bilinear.png")
>>> image = Image.open(StringIO.StringIO(data)); image.resize((36,36), Image.BICUBIC).save("/home/ptarjan/www/tmp/metaward/bicubic.png")
>>> image = Image.open(StringIO.StringIO(data)); image.resize((36,36), Image.NEAREST).save("/home/ptarjan/www/tmp/metaward/nearest.png")
>>>
>>> image = Image.open(StringIO.StringIO(data)); image.thumbnail((36,36), Image.ANTIALIAS); image.save("/home/ptarjan/www/tmp/metaward/antialias-thumb.png")
>>> image = Image.open(StringIO.StringIO(data)); image.thumbnail((36,36), Image.BILINEAR); image.save("/home/ptarjan/www/tmp/metaward/bilinear-thumb.png")
>>> image = Image.open(StringIO.StringIO(data)); image.thumbnail((36,36), Image.BICUBIC); image.save("/home/ptarjan/www/tmp/metaward/bicubic-thumb.png")
>>> image = Image.open(StringIO.StringIO(data)); image.thumbnail((36,36), Image.NEAREST); image.save("/home/ptarjan/www/tmp/metaward/nearest-thumb.png")
>>>
>>> image = Image.open(StringIO.StringIO(data)); image.convert("RGB").resize((36,36), Image.ANTIALIAS).save("/home/ptarjan/www/tmp/metaward/antialias-rgb.png")
>>> image = Image.open(StringIO.StringIO(data)); image.convert("RGB").resize((36,36), Image.BILINEAR).save("/home/ptarjan/www/tmp/metaward/bilinear-rgb.png")
>>> image = Image.open(StringIO.StringIO(data)); image.convert("RGB").resize((36,36), Image.BICUBIC).save("/home/ptarjan/www/tmp/metaward/bicubic-rgb.png")
>>> image = Image.open(StringIO.StringIO(data)); image.convert("RGB").resize((36,36), Image.NEAREST).save("/home/ptarjan/www/tmp/metaward/nearest-rgb.png")

But the results look much worse that just resizing in firefox.

http://paulisageek.com/tmp/metaward/images.html

How can I get a similar effect to the firefox result using PIL (or another python image library)?

EDIT : Hover your mouse to see what each image is

It looks like the RGB and then ANTIALIS looks the best. Any other recommendations?

For reference, this is the one that looked the best :

>>> image = Image.open(StringIO.StringIO(data)); 
>>> image.convert("RGB").resize((36,36), Image.ANTIALIAS)
A: 

Try using the resize() method instead of thumbnail(). In my experience, they behave very differently.

Also, your code shows reading a .gif, but your original is .png. Make sure you really have all the original data before you start reducing it.

Ned Batchelder
Sorry, I cut out the line where I made original. But yeah, it was just a conversion.I'll try resize, and compare.
Paul Tarjan
The example page now is all resize(), and they still look much worse than the FF way. Any other suggestions?
Paul Tarjan
+7  A: 

I resized the "original" with Python and found the same results as you did. I also resized the "original" with GIMP and I got the same (if not inferior) quality. This made me suspect that Firefox cheats. Possibly it converts to RGB ("original" mode is indexed color). Thus the following code:

import Image
im=Image.open("beta-icon.gif")
im = im.convert("RGB")
im=im.resize((36,36), Image.ANTIALIAS)
im.save("q5.png")

The result is almost as good as that of Firefox.

cyberthanasis
Would this be a general purpose strategy to get good thumbnails? If you want an example of my corpus, I have about 10k images : http://metaward.com/awards
Paul Tarjan
Definitely. Resizing images with indexed colors is not usually providing good results. If you do not care about preserving the palette, then you should always move to RGB, then resize and (in case) reduce again the color depth.
Roberto Liffredo
Thanks Roberto. Why wouldn't PIL do that by default then if it is a known method?
Paul Tarjan
@Paul: Because it is no longer an indexed image with a 256 color palette as it was before. Changing the mode (or even the palette) is by default is hardly expected behavior.
Lennart Regebro
A: 

It looks like the RGB and then ANTIALIS looks the best. Any other recommendations?

No, that is indeed the expected result. Any resizing done in the original limited palette mode is likely to produce jaggy rubbish because of the lack of available in-between colours in the palette; and ANTIALIAS is the only resize filter that is intended to be used for downscaling: BILINEAR and BICUBIC really do only take two pixels per axis and blend between them, which is fine for upscaling but doesn't work at all when one or both axes are downscaled.

Unfortunately thumbnail() has never really worked properly so you have to do it yourself.

bobince
then I'd love to have .thumbnail be removed and replaced with .thumbnail(size) which converts the palette if needed, and then uses resize . As a newcommer to PIL, .thumbnail seemed like exactly what I needed.
Paul Tarjan
Indeed, it is one of the dodgy corners of PIL that could be improved, but also an attractive-looking trap for the new user.
bobince
Actually, doing it with the RGB I lost the alpha channel. Any way to keep that?
Paul Tarjan
RGBA.
bobince