python-3.x - Python3 Tkinter 和 Pillow:如何在画布上旋转图像
问题描述
我想通过单击画布来移动画布周围的乌龟,乌龟应该指向它移动的方向。移动部分可以工作,但旋转功能会导致图像失真和损坏。
我做错了什么,我该如何解决这个问题?
我有一个类可以将乌龟的图像添加到画布上:
class TurtleImage:
"""
A Turtle image that will be placed on the canvas that is given in the ctor.
The turtle can be moved around the canvas with the move() method.
"""
def __init__(self, canvas : Canvas):
self.__turtle_file : str = self.__find_file("turtle_example/turtle.png")
self.__canvas = canvas
self.__pilImage : PngImagePlugin.PngImageFile = PILImage.open(self.__turtle_file)
self.__pilTkImage : ImageTk.PhotoImage = ImageTk.PhotoImage(self.__pilImage)
self.__turtle_id : int = canvas.create_image(100,100, image=self.__pilTkImage)
self.__is_moving = False
这个类还有一个方法可以让海龟在画布上移动。它在 x 方向、y 方向或两者上将海龟移动 1 个像素,然后在由 speed 参数确定的时间延迟后安排自己再次被调用。它还应该旋转海龟,使其指向正确的方向:
def move(self, dest_x : int, dest_y :int, speed : float = 0.1):
self.__is_moving = True
delay_ms = math.floor(1/speed)
current_x, current_y = self.__canvas.coords(self.__turtle_id)
delta_x = 1 if current_x < dest_x else -1 if current_x > dest_x else 0
delta_y = 1 if current_y < dest_y else -1 if current_y > dest_y else 0
angle = math.atan2(delta_y,delta_x)
self.__rotate(angle)
if (delta_x, delta_y) != (0, 0):
self.__canvas.move(self.__turtle_id, delta_x, delta_y)
if (current_x, current_y) != (dest_x, dest_y):
self.__canvas.after(delay_ms, self.move, dest_x, dest_y, speed)
else:
self.__is_moving = False
因为画布没有旋转其对象的能力,所以我必须将对象替换为自身的旋转版本:
def __rotate(self, angle : float):
self.__pilImage = self.__pilImage.rotate(angle)
self.__pilTkImage = ImageTk.PhotoImage(self.__pilImage)
self.__replace_image(self.__pilTkImage)
def __replace_image(self, new_image : ImageTk.PhotoImage):
self.__canvas.itemconfig(self.__turtle_id, image = new_image)
四处移动可以正常工作,但是旋转功能会导致图像失真和损坏,并且每次调用都会变得更糟。
你能告诉我为什么这不起作用,我需要做什么来解决它?
这是该海龟在旋转前后的屏幕截图:
解决方案
我找到了解决方案,我必须重新打开文件:
def __rotate(self, angle : float):
self.__pilImage = PILImage.open(self.__turtle_file)
self.__pilImage = self.__pilImage.rotate(angle)
self.__pilTkImage = ImageTk.PhotoImage(self.__pilImage)
self.__replace_image(self.__pilTkImage)
我不知道为什么。
推荐阅读
- python - 扬声器在使用pyttsx3将文本转换为语音时会产生静态噪音,并且playsound在使用它进行TTS操作时会抛出错误
- r - 变异后如何将 t.test() 应用于多对列
- python - 根据列表中每个元素的首字母创建字符串
- sapui5 - 如何在控制器中获取 UI5 框架的版本?
- ios - 如何在 SwiftUI 中使用 Path 创建贝塞尔曲线
- delphi - 如何使用 VCL 主题更改 DropDownList 组合框的“标签/编辑”区域的字体颜色?
- applescript - 如何使用 AppleScript 和 Calculator.app 自动选择小数位数
- javascript - 迭代具有未知级别的深层嵌套对象并根据用户提供的条件添加删除键/值
- javascript - 我无法获得包含的变量。为什么?
- javascript - Quart,聊天服务器示例