Python PIL:保持线条的最佳缩放方法

10 投票
2 回答
9469 浏览
提问于 2025-04-16 23:48

我有一幅二维图像,背景是黑色的,白色的线条(是从Autocad导出的),我想用Python PIL库制作一个缩略图,保持线条的样子。

但是我用'thumbnail'这个方法得到的结果只是一个黑色的图片,上面散落着一些白点。

需要注意的是,如果我把这个图片放到一个固定宽度的IMG标签里,我就能得到我想要的效果(但那样整个图片会被完全加载)。

根据你们的评论,这里是我的示例代码:

from PIL import Image
fn = 'filename.gif'
im = Image(fn)
im.convert('RGB')
im.thumbnail((300, 300), Image.ANTIALIAS)
im.save('newfilename.png', 'PNG')

我该怎么做呢?

2 个回答

4

默认情况下,im.resize使用的是NEAREST这个过滤器,这样做会导致你看到的情况——信息会丢失,除非正好落在合适的像素上。

你可以试着调用

im.resize(size, Image.BILINEAR)

这样做应该能保留你的线条。如果还是不行,可以试试Image.BICUBIC或者Image.ANTIALIAS。这些方法都比NEAREST效果要好。

15

默认情况下,thumbnail使用的缩放方法是NEAREST,这其实是个很糟糕的选择。比如说,如果你把图片缩小到原来的五分之一,它会输出一个像素,然后把接下来的四个像素都丢掉。这样一来,结果中出现一条只有一个像素宽的线的几率只有五分之一,根本不一定能看到!

让人惊讶的是,BILINEAR和BICUBIC这两种方法也没好到哪里去。它们会用一个公式,参考离目标点最近的两个或三个像素,但还是有很多像素没有被考虑到,而且这个公式会让线条变得不那么明显。

最好的选择是ANTIALIAS,这种方法似乎会考虑到原始图像的所有像素,不会丢掉任何像素。虽然线条会变得淡一些,但不会完全消失;如果需要的话,你还可以再做一步来提高对比度。

需要注意的是,如果你处理的是调色板图像,也就是im.mode == 'P',所有这些方法都会退回到NEAREST。你必须始终转换为'RGB'格式。

from PIL import Image
im = Image.open(fn)
im = im.convert('RGB')
im.thumbnail(size, Image.ANTIALIAS)

这里有一个来自electronics.stackexchange网站的例子 https://electronics.stackexchange.com/questions/5412/easiest-and-best-poe-ethernet-chip-micro-design-for-diy-interface-with-custom-ard/5418#5418

使用默认的NEAREST算法,我想这和你得到的结果类似:

NEAREST

使用ANTIALIAS算法:

ANTIALIAS

撰写回答