当输入图像旋转给定角度并裁剪以避免任何非图像区域同时保持原始图像宽高比时,如何找出最终图像的宽度和高度。
例子:
当输入图像旋转给定角度并裁剪以避免任何非图像区域同时保持原始图像宽高比时,如何找出最终图像的宽度和高度。
例子:
W/t
矩形(由绿色和黄色三角形围住)是带有 extend=True
的旋转图像宽高比。下面是获取w
和h
的方法。
image = Image.open(...)
rotated = image.rotate(degrees, Image.BICUBIC, True)
aspect_ratio = float(image.size[0]) / image.size[1]
rotated_aspect_ratio = float(rotated.size[0]) / rotated.size[1]
angle = math.fabs(degrees) * math.pi / 180
if aspect_ratio < 1:
total_height = float(image.size[0]) / rotated_aspect_ratio
else:
total_height = float(image.size[1])
h = total_height / (aspect_ratio * math.sin(angle) + math.cos(angle))
w = h * aspect_ratio
w
,高为h
的尺寸在中心进行裁剪,得到最终的图片。宽高比 = a = w/h
,那么不应该是 w = a / h
而不是 w = h * a
吗? - martineauW0和H0分别为原始矩形的宽度和高度。
D0为原始矩形的对角线(斜边)长度。
W1和H1分别为旋转后矩形的填充宽度和高度。
W2和H2分别为目标矩形的宽度和高度。
D2为目标矩形的对角线(斜边)长度。
E是复杂且瞬态的。
你可能需要预先计算sin(A)、cos(A)和tan(A),因为它们会被重复使用。
它们由两个组成部分构成,即构成每个长度的两条三角形边。
W0 = # original rectangle width
H0 = # original rectangle height
cosA = cos(A)
sinA = sin(A)
tanA = tan(A)
W1 = W0 * cosA + H0 * sinA
H1 = H0 * cosA + W0 * sinA
E = W0 / (1 + tanA / W0 * H0)
W2 = E / tanA # requested width
H2 = W2 / W0 * H0 # requested height
编辑:按照要求,我最好的猜测是我所说的E:
r0 = w2/h2
h2 = (w0-e1) / sin(A)
h2 = e1/ cos(A) / r0
(w0-e1) / sin(A) = e1/ cos(A) / r0
x = cos(A) / sin(A)
e1 = w0 * x / (1/r0 + x)
E是w2的水平分量,延伸通过线a+b。然后计算a
和b
,使用纵横比和正弦/余弦来计算。项被取消,声音变高,这就是我最终得到的结果。
from PIL import Image
def cropp_rotated(image, degrees):
x, y = image.size
cosA = abs(math.cos(math.radians(degrees)))
sinA = abs(math.sin(math.radians(degrees)))
a = x * cosA
b = x * sinA
relation = a / (a + b)
right_indent1 = a - x * relation * cosA
relation = b / (a + b)
bottom_ident1 = b - x * relation *sinA
c = y * cosA
d = y * sinA
relation = c / (c + d)
right_indent2 = c - y * relation * cosA
relation = d / (c + d)
bottom_ident2 = d - y * relation *sinA
right_indent = max(right_indent1, right_indent2)
top_indent = max(bottom_ident1, bottom_ident2)
#size of rotated image:
w_rotated = x * cosA + y * sinA
h_rotated = y * cosA + x * sinA
box = (
int(right_indent),
int(top_indent),
int(w_rotated - right_indent),
int(h_rotated - top_indent))
return box
我只是为了获取图像的真实大小而导入PIL。 你不必导入PIL,可以通过其他方式获取图像大小。