Python PyCairo:如何调整大小&;将图像按其中心旋转到最终画布
使用PyCairo,我希望能够有一种方法,可以在上下文中放置、调整和旋转给定的ImageSurface,但可以按图像的中心(而不是左上角)旋转 好的,我已经尝试了我在这里找到的例子,但是没有成功。 让我们详细介绍一下“上下文” 我有一个“最终”的图像表面(比如a),上面写着一些其他的图像和文本。 我想在它上面放置另一个ImageSurface(比如B),在一个指定的位置,这个位置是将B放置在a上的左上角。然后我需要调整B的大小(减小它的大小),并通过它的中心旋转它,而不是通过它的左上角 以下是所需结果的示例: 我尝试了以下方法,但没有成功:Python PyCairo:如何调整大小&;将图像按其中心旋转到最终画布,python,image-processing,pycairo,Python,Image Processing,Pycairo,使用PyCairo,我希望能够有一种方法,可以在上下文中放置、调整和旋转给定的ImageSurface,但可以按图像的中心(而不是左上角)旋转 好的,我已经尝试了我在这里找到的例子,但是没有成功。 让我们详细介绍一下“上下文” 我有一个“最终”的图像表面(比如a),上面写着一些其他的图像和文本。 我想在它上面放置另一个ImageSurface(比如B),在一个指定的位置,这个位置是将B放置在a上的左上角。然后我需要调整B的大小(减小它的大小),并通过它的中心旋转它,而不是通过它的左上角 以下是所
def draw_rotated_image(ctx, image_surface, left, top, width, height, angle):
ctx.save()
w = image_surface.get_width()
h = image_surface.get_height()
cl = left / (width/w)
ct = top / (height/h)
ctx.rotate(angle*3.1415927/180)
ctx.scale(width/w, height/h)
ctx.translate(cl + (-0.5*w),ct + (-0.5*h) )
ctx.set_source_surface(image_surface, 0, 0)
ctx.paint()
ctx.restore()
return
非常感谢你的帮助:)嗯,我终于成功了!(感谢我14岁的儿子,他让我修改了三角学)
我想在这里解释我的解决方案。
首先,我不是数学家。所以可能有一个最好的方法,当然我的解释有错误,但我只是解释我用来得到好结果的逻辑方法
最好的办法是首先围绕矩形画一个圆,因为我们需要根据所需的角度,围绕矩形的圆移动矩形的左上角。
为了得到矩形圆的半径,我们需要计算它的假设,然后除以2:
hypothenuse = math.hypot(layerWidth,layerHeight)
radius = hypothenuse / 2
然后我们将能够围绕矩形画一个圆
第二,我们需要知道这个圆上的哪个角度是矩形的左上角。
因此,我们需要计算矩形的反切线,即弧tan(高度/宽度)。
但因为我们想知道离0°有多少度,我们需要计算相反的弧tan(宽度/高度)
最后,另一个奇点是开罗0°实际上是90°,所以我们必须再次旋转
这可以通过以下简单的图形显示:
那么最后,需要理解什么呢?
如果要绘制一个由圆心旋转的具有角度的图层,左上角点将根据所需角度围绕圆移动。
给定角度为0的左上角位置需要为“参考”
因此,我们需要获得新的X-Y位置,在该位置开始放置层,以便能够旋转它:
现在,我们可以编写一个函数,返回左上角矩形的X-Y位置,在该位置以给定角度绘制矩形:
最后,这里是如何将其用于我们想要在上下文上调整大小、旋转和写入的图像:
def draw_rotated_image(ctx, image_surface, left, top, width, height, angle=0.0, alpha=1.0):
ctx.save()
w = image_surface.get_width()
h = image_surface.get_height()
# get the new top-left position according to the given angle
newTopLeft = getTopLeftForRectangleAtAngle(left, top, width, height, angle)
# translate
ctx.translate(newTopLeft[0], newTopLeft[1])
# rotate
ctx.rotate(angle * math.pi / 180)
# scale & write
ctx.scale(width/w, height/h)
ctx.set_source_surface(image_surface, 0, 0)
ctx.paint_with_alpha(alpha)
ctx.restore()
return
def draw_rotated_image(ctx, image_surface, left, top, width, height, angle=0.0, alpha=1.0):
ctx.save()
w = image_surface.get_width()
h = image_surface.get_height()
# get the new top-left position according to the given angle
newTopLeft = getTopLeftForRectangleAtAngle(left, top, width, height, angle)
# translate
ctx.translate(newTopLeft[0], newTopLeft[1])
# rotate
ctx.rotate(angle * math.pi / 180)
# scale & write
ctx.scale(width/w, height/h)
ctx.set_source_surface(image_surface, 0, 0)
ctx.paint_with_alpha(alpha)
ctx.restore()
return