1

我想旋转黑白图像。我正在尝试按如下方式使用旋转功能:

image.rotate(angle, fillcolor=255)

我需要旧版本的 Python 和 Pillow,它们不支持“fillcolor”参数。由于某些限制,我无法升级到较新的版本,也无法使用任何外部库。

是否有另一种方法可以使用 Pillow 用白色填充旋转图像之外的区域?

旋转图像在旋转部分之外的区域为黑色。我想用白色填充它。

原图:原图

旋转:旋转图像

4

3 回答 3

3

您可以尝试通过Image.composite()对原始图像进行插值,以消除黑条/边框。

from PIL import Image

img = Image.open(r"Image_Path").convert("RGBA")

angle = 30

img = img.rotate(angle)

new_img = Image.new('RGBA', img.size, 'white')

Alpha_Image = Image.composite(img, new_img, img)

Alpha_Image = Alpha_Image.convert(img.mode)

Alpha_Image.show()

上面的代码接收一个图像,将其转换为模式RGBA(此过程需要 Alpha),然后将图像旋转30 。之后,它创建一个RGBA与原始图像具有相同尺寸的模式的空 Image 对象,每个像素具有255每个通道的默认值(即RGB 为纯白色,Alpha/Transparency 上下文中为全不透明度)。然后使用原始图像的蒙版(我们使用第一张图像的透明度蒙版)将原始图像与这个空图像进行插值。这会产生所需的图像,其中黑条/边缘被白色替换。最后,我们将图像颜色空间转换为原始颜色空间。

原始图像:-

在此处输入图像描述

旋转 30 度后的图像:-

在此处输入图像描述

于 2019-06-26T07:37:31.667 回答
0

一个一直对我有用的尴尬选项,就像我的工具一样,我总是在旋转的图像周围得到一个浅灰色的“边框”,这会干扰填充:

  • 在未旋转的图像上添加边框并使用该边框的填充颜色。边界操作是无损的,填充将是准确的(并且容易)。

  • 旋转带边框的图像。接缝现在也将正确(但不精确,除非您旋转 45° 或 90°)。

  • 使用三角函数计算旋转边框的大小。结果将不准确(即“131.12 像素”)。通常您可以反向执行此操作,从旋转图像上的精确边框开始并计算您需要添加的边框,然后调整边框宽度以使非旋转边框精确。示例:使用 170 像素的旋转边框,您将获得 140.3394 像素的非旋转边框。所以你使用一个 510 像素的旋转边框,导致需要添加一个 421.018 像素的非旋转边框。这足够接近 421 像素,可以接受。

  • 删除旋转的边框。

这也有助于避免图像的剪切部分附近的一些伪影从旋转的图像上脱落。

它的缺点是您最终会进行更大规模的旋转,具有更高的内存消耗和计算时间,特别是如果您使用更大的边界来提高精度。

于 2019-06-26T06:40:27.270 回答
0

编辑:由于不允许使用外部库,我建议裁剪您想要的矩形并将其粘贴到原始图像上,这可以使用幻数(矩形坐标)来完成,这对我有用(您可能需要 tweek一点)

im = Image.open("mFul4.png")
rotated = im.rotate(105)
box = (55, 65,200,210)
d = rotated.crop(box=box)
im.paste(d, box=box)
im.save("ex.bmp" )

和输出

在此处输入图像描述

Edit2:这是最丑陋的方式,但它有效,您可能需要稍微调整一下魔术数字以使其更精确,我正在处理您给定的图像,所以无法判断我何时过度使用它。它产生相同的输出

from PIL import Image
im = Image.open("mFul4.png")
angle=105
cos = 0.240959049 # -cos(angle)
d = im.rotate(angle)
pix = d.load()

tri_x = 120
for i in range(4): # 4 triangles
    for j in range(tri_x, -1, -1):
        for k in range(int((tri_x-j)*cos)+1, -1, -1):
            x,y =( j, k )if i <1 else (d.size[0]-j-1, d.size[1]-k-1)
            if i in [2,3]:
                y, x = (d.size[0] - j-2 , k) if i <3 else (j, d.size[1] - k)
            pix[x,y] = (255, 255, 255, 255)
d.show()
于 2019-06-26T06:30:06.193 回答