Python Image Library: clean Downsampling

Li Haoyi picture Li Haoyi · Oct 29, 2011 · Viewed 7k times · Source

I've been having trouble trying to get PIL to nicely downsample images. The goal, in this case, is for my website to automagically downsample->cache the original image file whenever a different size is required, thus removing the pain of maintaining multiple versions of the same image. However, I have not had any luck. I've tried:

image.thumbnail((width, height), Image.ANTIALIAS)
image.save(newSource)

and

image.resize((width, height), Image.ANTIALIAS).save(newSource)

and

ImageOps.fit(image, (width, height), Image.ANTIALIAS, (0, 0)).save(newSource)

and all of them seem to perform a nearest-neighbout downsample, rather than averaging over the pixels as it should Hence it turns images like

http://www.techcreation.sg/media/projects//software/Java%20Games/images/Tanks3D%20Full.png

to

http://www.techcreation.sg/media/temp/0x5780b20fe2fd0ed/Tanks3D.png

which isn't very nice. Has anyone else bumped into this issue?

Answer

kindall picture kindall · Oct 29, 2011

That image is an indexed-color (palette or P mode) image. There are a very limited number of colors to work with and there's not much chance that a pixel from the resized image will be in the palette, since it will need a lot of in-between colors. So it always uses nearest-neighbor mode when resizing; it's really the only way to keep the same palette.

This behavior is the same as in Adobe Photoshop.

You want to convert to RGB mode first and resize it, then go back to palette mode before saving, if desired. (Actually I would just save it in RGB mode, and then turn PNGCrush loose on the folder of resized images.)