当使用PIL进行thumbnail()和crop()操作时,是否会在图像底部产生伪影?如果是,你有什么解决方法?

3
当我使用PIL对图像进行缩略图和裁剪时,最后一行像素会出现伪影 -- 它们要么是大部分黑色,有着强烈的颜色斑点,要么是图像中未经调整大小的区域(即该行像素以原始分辨率呈现,并未随其余部分一起缩小)。这种情况在没有裁剪的缩略图()中似乎不会发生。无论是否在裁剪后的图像上调用load()都会出现这种情况。
为了视觉效果,我一直将图像缩略到1像素更大的尺寸,然后裁剪到相同的尺寸。这似乎有效,但有点不太规范。我想知道是否有正确的解决方法。

1
使用resize会解决这个问题吗?我一直对thumbnail的质量有问题。 - bobince
得分! 是的,那绝对解决了问题。现在图像看起来正确了! - jvanasco
1个回答

2

是的,我也遇到过这个问题。对我来说,这是一个学习练习,因为我从未使用PIL裁剪或创建缩略图...

thumbnail(size, filter=None)

在原地用给定大小的新图像(第2页)替换原始图像。可选的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 像素的黑线。

解决方案可以是在缩略图的实际尺寸内进行裁剪,或者找出如何忽略宽高比创建缩略图。


谢谢@manifest;我的代码已经防御了像你这样的情况,并且调整到了裁剪的确切大小。问题不在于黑线,而是存在一个带有颜色斑点的黑线或者似乎没有被调整大小的人工制品线。 - jvanasco
我将从1600 x 1200的图像缩略为50 x 37,然后我将我的裁剪位置更改为“下方”37。黑线消失了,没有任何伪影。我不确定你可能遇到的问题是什么,但祝你好运! - manifest
1
这是我使用的代码的pastebin链接:http://pastebin.com/T3zMemTv感谢@bobince,我将重构thumbnail()以适用于所有情况--而不仅仅是裁剪方法。如果有帮助,请随意使用此代码。 - jvanasco

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接