如何防止PIL在将图像旋转90度时交换高度/宽度?

13

我正在使用PIL来旋转一张图片。通常情况下这个方法是有效的,但当我把图片旋转90°或者270°时,会发现x和y的尺寸互换了。也就是说,给定以下的图片:

>>> img.size
(93, 64)

如果我将它旋转89度,就会得到这样:

>>> img.rotate(89).size
(93, 64)

当我输入91度时,得到了这个:

>>> img.rotate(91).size
(93, 64)

但是如果我将其旋转90°或270°,我发现高度和宽度互换了:

>>> img.rotate(90).size
(64, 93)
>>> img.rotate(270).size
(64, 93)

如何正确地防止这种情况发生?


1
看起来90度和270度是特殊情况,符合大多数人的预期。你可能运气不佳,但你可以使用“expand”选项使其保持一致。 - Mark Ransom
我认为仅仅使用expand可能不会起作用;因为我正在编写适应固定屏幕大小的程序。或许需要结合expand和某种形式的crop操作。 - larsks
3
给其他谷歌用户的更新:优秀的PIL分支——Pillow已在3.0.0版本中修复了这个问题。现在旋转90度或270度将保持相同的尺寸,因此如果您想要实际改变尺寸,需要设置expand=True。 - Agargara
1个回答

9
我希望有人能提出更优雅的解决方案,但现在似乎这个方案可以使用:
img = Image.open('myimage.pbm')

frames = []
for angle in range(0, 365, 5):
    # rotate the image with expand=True, which makes the canvas
    # large enough to contain the entire rotated image.
    x = img.rotate(angle, expand=True)

    # crop the rotated image to the size of the original image
    x = x.crop(box=(x.size[0]/2 - img.size[0]/2,
               x.size[1]/2 - img.size[1]/2,
               x.size[0]/2 + img.size[0]/2,
               x.size[1]/2 + img.size[1]/2))

    # do stuff with the rotated image here.

对于除了90°和270°之外的角度,这将导致与设置expand=False并不关心crop操作时相同的行为。

1
请注意,“expand”选项还会减少一个维度,因此仅裁剪是不够的 - 您需要添加一些背景。 - Mark Ransom
我在 expand 中没有看到那个问题。至少对于我尝试做的事情,这似乎非常有效。你可以在这里看到结果。由于最终将在128x64液晶显示屏上显示,因此它的分辨率较低。 - larsks
1
据说PIL在过去的4年中有所改进,对我来说只需使用img.rotate(90, expand=True)即可。 - mauve

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