简体   繁体   English

PIL: Image resizing: 类似于firefox的算法

[英]PIL: Image resizing : Algorithm similar to firefox's

I'm getting about the same bad looking resizing from all the 4 algorithms of PIL我从 PIL 的所有 4 种算法中得到了同样糟糕的调整大小

>>> 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.但是结果看起来比在 Firefox 中调整大小要糟糕得多。

http://paulisageek.com/tmp/metaward/images.html 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)?如何使用 PIL(或其他 python 图像库)获得与 firefox 结果类似的效果?

EDIT : Hover your mouse to see what each image is编辑:将鼠标悬停以查看每个图像是什么

It looks like the RGB and then ANTIALIS looks the best.它看起来像 RGB,然后 ANTIALIS 看起来最好。 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)

I resized the "original" with Python and found the same results as you did.我用 Python 调整了“原始”的大小,发现了与您相同的结果。 I also resized the "original" with GIMP and I got the same (if not inferior) quality.我还用 GIMP 调整了“原始”的大小,我得到了相同的(如果不是劣质的话)质量。 This made me suspect that Firefox cheats.这让我怀疑 Firefox 作弊。 Possibly it converts to RGB ("original" mode is indexed color).可能它会转换为 RGB(“原始”模式是索引颜色)。 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.结果几乎和 Firefox 一样好。

It looks like the RGB and then ANTIALIS looks the best.它看起来像 RGB,然后 ANTIALIS 看起来最好。 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.并且 ANTIALIAS 是唯一旨在用于缩小尺寸的调整大小过滤器:BILINEAR 和 BICUBIC 实际上只在每个轴上使用两个像素并在它们之间混合,这对于放大来说很好,但当一个或两个轴都是缩小。

Unfortunately thumbnail() has never really worked properly so you have to do it yourself.不幸的是 thumbnail() 从来没有真正正常工作,所以你必须自己做。

Try using the resize() method instead of thumbnail() .尝试使用resize()方法而不是thumbnail() In my experience, they behave very differently.根据我的经验,他们的行为非常不同。

Also, your code shows reading a.gif, but your original is.png.此外,您的代码显示阅读 a.gif,但您的原始代码是 .png。 Make sure you really have all the original data before you start reducing it.在开始减少数据之前,请确保您确实拥有所有原始数据。

The image posted is an indexed image .发布的图像是索引图像 Its mode is 'P' if you read it via PIL.如果您通过 PIL 读取它,它的模式是'P' The PIL documentation on Image.resize() for the resample parameter states that:关于Image.resize()的 resample 参数的 PIL 文档指出:

If the image has mode “1” or “P”, it is always set to PIL.Image.NEAREST如果图像的模式为“1”或“P”,则始终设置为 PIL.Image.NEAREST

So PIL will use nearest filter for resizing indexed images, which is a low quality filter .所以 PIL 将使用最近的过滤器来调整索引图像的大小,这是一个低质量的过滤器

The right way is to convert the image mode to RGB and then use resize with a high-quality filter such as Image.LANCZOS .正确的方法是将图像模式转换为RGB ,然后使用高质量过滤器(如Image.LANCZOS )调整大小。 By the way, Image.ANTIALIAS is now the same as Image.LANCZOS , source here .顺便说一句, Image.ANTIALIAS现在与Image.LANCZOS相同,来源在这里

import Image
img = Image.open("beta-icon.gif").convert("RGB")
img = img.resize((36,36), Image.LANCZOS)
img.save("img-resized.png")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM