【问题标题】:Rotating a square in PIL在 PIL 中旋转一个正方形
【发布时间】:2016-01-12 15:45:29
【问题描述】:

使用 PIL,我想通过指定正方形边长和旋转角度在图像上绘制旋转正方形。正方形应该是白色的,背景是灰色的。例如,下图旋转了 45 度:

我知道如何在 PIL 中进行旋转的唯一方法是旋转整个图像。但如果我从下图开始:

然后将它旋转 45 度,我得到了这个:

该方法只是引入黑色部分来填充图像的“未定义”区域。

我怎样才能只旋转正方形?

生成我原来的正方形(第二个图)的代码如下:

from PIL import Image

image = Image.new('L', (100, 100), 127)
pixels = image.load()

for i in range(30, image.size[0] - 30):
    for j in range(30, image.size[1] - 30):
        pixels[i, j] = 255

rotated_image = image.rotate(45)
rotated_image.save("rotated_image.bmp")

【问题讨论】:

  • 我不太确定您要的是什么。 “之前”和“之后”的图像在这里可能很有用。
  • 我现在已经相应地更新了问题!
  • stackoverflow.com/questions/5252170/… 的可能重复(或至少这看起来可以回答问题)

标签: python python-imaging-library pillow


【解决方案1】:

如果你只想在任意角度画一个纯色正方形,你可以用三角法计算旋转正方形的顶点,然后用polygon画出来。

import math
from PIL import Image, ImageDraw

#finds the straight-line distance between two points
def distance(ax, ay, bx, by):
    return math.sqrt((by - ay)**2 + (bx - ax)**2)

#rotates point `A` about point `B` by `angle` radians clockwise.
def rotated_about(ax, ay, bx, by, angle):
    radius = distance(ax,ay,bx,by)
    angle += math.atan2(ay-by, ax-bx)
    return (
        round(bx + radius * math.cos(angle)),
        round(by + radius * math.sin(angle))
    )

image = Image.new('L', (100, 100), 127)
draw = ImageDraw.Draw(image)

square_center = (50,50)
square_length = 40

square_vertices = (
    (square_center[0] + square_length / 2, square_center[1] + square_length / 2),
    (square_center[0] + square_length / 2, square_center[1] - square_length / 2),
    (square_center[0] - square_length / 2, square_center[1] - square_length / 2),
    (square_center[0] - square_length / 2, square_center[1] + square_length / 2)
)

square_vertices = [rotated_about(x,y, square_center[0], square_center[1], math.radians(45)) for x,y in square_vertices]

draw.polygon(square_vertices, fill=255)

image.save("output.png")

结果:

【讨论】:

    【解决方案2】:

    让我们推广到一个矩形:

    • x 的长度 l y 的宽度 w
    • 使用“旋转矩阵”。

    轮换代码:

    import math
    
    def makeRectangle(l, w, theta, offset=(0,0)):
        c, s = math.cos(theta), math.sin(theta)
        rectCoords = [(l/2.0, w/2.0), (l/2.0, -w/2.0), (-l/2.0, -w/2.0), (-l/2.0, w/2.0)]
        return [(c*x-s*y+offset[0], s*x+c*y+offset[1]) for (x,y) in rectCoords]
    

    绘图代码:

    from PIL import Image
    from PIL import ImageDraw
    import math
    
    L=512; W=512
    image = Image.new("1", (L, W))
    draw = ImageDraw.Draw(image)
    
    vertices = makeRectangle(100, 200, 45*math.pi/180, offset=(L/2, W/2))
    draw.polygon(vertices, fill=1)
    
    image.save("test.png")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-21
      • 2017-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-05
      相关资源
      最近更新 更多