如何通过中心坐标、宽高及角度绘制带填充值的旋转矩形?
First off, I feel your pain—having to cobble together rotation logic every time you need a rotated filled rectangle is annoying, and none of the major libraries (OpenCV, PIL, Matplotlib) have that exact one-liner you're asking for. But the good news is we can easily wrap the necessary steps into a custom function that matches your desired clean API.
Let's Build the Wrapper Function
Below are practical implementations for both OpenCV and PIL/Pillow, the most common libraries for image drawing tasks.
OpenCV Implementation
OpenCV handles geometric transformations smoothly, and we can skip full image warping by calculating the rotated rectangle's vertices directly to fill it:
import cv2 import numpy as np def draw_rotated_filled_rectangle(img, centerx, centery, width, height, angle, value): # Convert angle to radians for math calculations angle_rad = np.deg2rad(angle) half_w = width / 2 half_h = height / 2 # Define rectangle corners relative to the center (0,0) corners = np.array([ [-half_w, -half_h], [half_w, -half_h], [half_w, half_h], [-half_w, half_h] ], dtype=np.float32) # Create rotation matrix rotation_matrix = np.array([ [np.cos(angle_rad), -np.sin(angle_rad)], [np.sin(angle_rad), np.cos(angle_rad)] ]) # Rotate corners and translate to the target center coordinates rotated_corners = np.dot(corners, rotation_matrix) + np.array([centerx, centery]) rotated_corners = rotated_corners.astype(np.int32).reshape((-1, 1, 2)) # Fill the rotated rectangle polygon cv2.fillPoly(img, [rotated_corners], color=value) return img
How to Use It
# Create a blank 500x500 grayscale image img = np.zeros((500, 500), dtype=np.uint8) # Draw your desired rotated rectangle: center (250,250), width 100, height 50, angle 30°, fill value 5 img = draw_rotated_filled_rectangle(img, 250, 250, 100, 50, 30, 5) # View the result cv2.imshow("Rotated Filled Rectangle", img) cv2.waitKey(0) cv2.destroyAllWindows()
PIL/Pillow Implementation
For PIL users, we can calculate rotated vertices and use ImageDraw.polygon() to fill the shape:
from PIL import Image, ImageDraw import math def draw_rotated_filled_rectangle(img, centerx, centery, width, height, angle, value): draw = ImageDraw.Draw(img) half_w = width / 2 half_h = height / 2 angle_rad = math.radians(angle) # Define corners relative to the center corners = [ (-half_w, -half_h), (half_w, -half_h), (half_w, half_h), (-half_w, half_h) ] # Rotate each corner and translate to target center rotated_corners = [] for x, y in corners: rotated_x = x * math.cos(angle_rad) - y * math.sin(angle_rad) + centerx rotated_y = x * math.sin(angle_rad) + y * math.cos(angle_rad) + centery rotated_corners.append((rotated_x, rotated_y)) # Fill the polygon with your desired value draw.polygon(rotated_corners, fill=value) return img
How to Use the PIL Version
# Create a blank 500x500 grayscale image img = Image.new("L", (500, 500), 0) # Draw the rotated rectangle img = draw_rotated_filled_rectangle(img, 250, 250, 100, 50, 30, 5) # View or save the result img.show()
Key Notes
- Both functions mimic the simple API you wanted, with the standard addition of passing the target image as the first parameter (this keeps it consistent with how drawing works in most libraries).
- The
valueparameter works for grayscale images (like your example with 5); for color images, pass a tuple such as(255, 0, 0)for red. - If you strictly want the
draw.rectangle(...)syntax you mentioned, you could wrap this into a class that holds a reference to your image—though the above functions are more flexible for most use cases.
内容的提问来源于stack exchange,提问作者Majid Azimi

