PIL:图像缩放:类似于Firefox的算法

11 投票
4 回答
8935 浏览
提问于 2025-04-15 14:07

我发现用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")

而且这些结果看起来比在Firefox里调整大小的效果要差得多。

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

我该怎么做才能用PIL(或者其他Python图像库)得到和Firefox一样的效果呢?

编辑:把鼠标悬停在图片上可以查看每张图片的内容。

看起来RGB和ANTIALIAS的效果最好。还有其他推荐吗?

作为参考,这个效果看起来是最好的:

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

4 个回答

0

试试用 resize() 方法,而不是 thumbnail()。根据我的经验,这两个方法的表现差别很大。

另外,你的代码里显示在读取一个 .gif 文件,但你最开始的是 .png 文件。确保在开始缩小之前,你真的有所有原始的数据。

1

看起来RGB和ANTIALIAS效果最好。还有其他推荐吗?

没有,这确实是预期的结果。在原始的有限调色板模式下进行任何缩放,可能会产生锯齿状的糟糕效果,因为调色板中没有足够的中间颜色。而ANTIALIAS是唯一一个专门用于缩小图像的缩放滤镜:BILINEAR和BICUBIC实际上只会取每个轴上的两个像素并进行混合,这在放大时效果不错,但在缩小时就完全不行了。

不幸的是,thumbnail()这个函数一直没有真正正常工作,所以你得自己来处理。

10

我用Python调整了“原始”图片的大小,发现结果和你一样。我还用GIMP调整了“原始”图片的大小,结果也差不多(甚至可能更差)。这让我怀疑Firefox可能在作弊。可能它把图片转换成了RGB格式(而“原始”模式是索引颜色)。所以我写了以下代码:

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

结果几乎和Firefox的一样好。

撰写回答