PIL在thumbnail()后再crop()时会在图像底部边缘产生伪影吗?如果是,有什么解决方法?

3 投票
1 回答
515 浏览
提问于 2025-04-15 19:35

当我用PIL库的thumbnail()方法处理一张图片,然后再用crop()裁剪时,最后一行的像素出现了问题——它们要么大部分是黑色,偶尔有一些亮色点,要么看起来像是没有缩放的区域(也就是说,这一行的像素保持在原来的分辨率,没有和其他部分一起缩小)。

如果只用thumbnail()而不裁剪,这个问题就不会出现。不管我是否在裁剪后的图片上调用load(),这个问题依然存在。

为了在视觉上解决这个问题,我尝试先把图片缩小到比目标大小大1个像素,然后再裁剪到目标大小。这样似乎有效。不过这有点像是个临时解决办法。我在想有没有更好的解决方案。

1 个回答

2

是的,这种情况我也遇到过。这对我来说是一个学习的过程,因为我之前从来没有用PIL裁剪或创建缩略图...

thumbnail(size, filter=None)

这个方法会把原来的图片替换成一个新的指定大小的图片。可选的filter参数和.resize()方法中的用法一样。这个操作会保持图片的长宽比例(高度 : 宽度)。生成的图片会尽可能大,但仍然会适应给定的大小。举个例子,如果图片im的大小是(400,150),那么在执行im.thumbnail((40,40))后,它的大小会变成(40,15)

那么,发生了什么呢:

  1. 你使用了thumbnail,它保持了长宽比例
  2. 你期待图片的大小是40 x 40
  3. 你裁剪的超出了缩略图的实际大小
  4. 底部很可能出现了一条黑色的条纹,因为裁剪超出了大小

我写的代码来重现这个问题:

def croptest(file, width, height):
    import Image as pil
    import os

    max_width = width
    max_height = height
    file, ext = os.path.splitext(file)

    img = pil.open(file)
    img.thumbnail((max_width, max_height), pil.ANTIALIAS)
    img.save(file + ".thumb.jpeg", 'JPEG')
    croppedImage = img.crop((10, 10, 40, 40))
    croppedImage.save(file + ".croppedthumb.jpeg", 'JPEG')

if __name__ == "__main__":
   croptest("Desktop.bmp", 50, 50)

Desktop.thumb.jpeg的大小是50 x 37,而Desktop.croppedthumb.jpeg的大小是30 x 30,所以我在底部有一条3像素高的黑线。

你的解决办法可以是裁剪到缩略图的实际大小以内,或者想办法创建一个不考虑长宽比例的缩略图。

撰写回答