With PIL, I want to draw a rotated square on an image, by specifying the square side length, and the rotation angle. The square should be white, and the background grey. For example, the following image has a rotation of 45 degrees:

The only way I know how to do rotations in PIL is by rotating the entire image. But if I start with the following image:

And then rotate it by 45 degrees, I get this:

That method just introduces black parts to fill in the "undefined" region of the image.
How can I rotate just the square?
The code to generate my original square (the second figure) is as follows:
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")
If all you want to do is draw a solid color square at some arbitrary angle, you can use trigonometry to calculate the vertices of the rotated square, then draw it with 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")
Result:

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With