C# 图像绕中心旋转问题:旋转后图像上下出现多余空白
Hey there! Let's figure out why you're seeing those unexpected top/bottom blank spaces after rotating your image at -61 degrees around its center. This is a common gotcha, and it almost always boils down to one of a few key mistakes in how you calculate the rotated canvas size or handle the rotation transform.
Common Causes & Fixes
1. Incorrect Rotated Canvas Size Calculation
The most frequent issue is using the wrong formula to compute the new width and height of the rotated image. The correct formula accounts for both the original dimensions and the absolute values of the sine/cosine of your rotation angle (since negative angles don't change the required canvas size—-61° is equivalent to 299° visually).
Here's the right formula (convert your angle to radians first!):
import math theta = math.radians(abs(-61)) # Convert -61° to radians, take absolute value original_width, original_height = img.size new_width = int(original_width * math.cos(theta) + original_height * math.sin(theta)) new_height = int(original_width * math.sin(theta) + original_height * math.cos(theta))
Mistake to avoid: Forgetting to use absolute values for sin(theta) and cos(theta), or using degrees directly in trigonometric functions (most languages/libraries use radians by default). Using negative sine values can lead to undersized or oversized canvases, causing gaps.
2. Misaligned Rotation Center & Translation
Even if you calculate the correct canvas size, if you don't properly translate the original image to align its center with the new canvas's center, you'll end up with uneven gaps.
For example, in OpenCV, you need to adjust the rotation matrix's translation components to shift the rotated image into the center of the new canvas:
import cv2 import numpy as np img = cv2.imread("your_image.jpg") h, w = img.shape[:2] angle = -61 center = (w // 2, h // 2) # Get base rotation matrix rot_mat = cv2.getRotationMatrix2D(center, angle, 1.0) # Calculate correct new dimensions theta = np.radians(abs(angle)) new_w = int(w * np.cos(theta) + h * np.sin(theta)) new_h = int(w * np.sin(theta) + h * np.cos(theta)) # Adjust translation to center the image on the new canvas rot_mat[0, 2] += (new_w - w) / 2 rot_mat[1, 2] += (new_h - h) / 2 # Perform rotation with the corrected matrix and size rotated_img = cv2.warpAffine(img, rot_mat, (new_w, new_h), borderMode=cv2.BORDER_CONSTANT)
In PIL/Pillow, you can avoid manual translation entirely by using the expand=True parameter in the rotate() method—it automatically calculates the correct canvas size and centers the rotated image:
from PIL import Image img = Image.open("your_image.png") rotated_img = img.rotate(-61, expand=True, center=(img.width//2, img.height//2))
3. Integer Truncation Issues
If you're truncating decimal values instead of rounding up when calculating new_width and new_height, you might end up with a canvas that's slightly too small (leading to cropping) or, in some cases, slightly too large (creating unnecessary gaps). Use math.ceil() instead of int() if you're calculating manually to ensure you cover the entire rotated image.
Quick Validation Check
Let's test with sample values to confirm:
- Original image: 100px × 100px
- Angle: -61° (cos(61) ≈ 0.4848, sin(61) ≈ 0.8746)
- Calculated new size: ~136px × 136px
If your code outputs a size significantly different from this, your formula is likely incorrect.
内容的提问来源于stack exchange,提问作者Evgeny Belov

