【问题标题】:Python3 Tkinter and Pillow: How to rotate an image while it is on a canvasPython3 Tkinter 和 Pillow:如何在画布上旋转图像
【发布时间】:2020-07-10 18:39:00
【问题描述】:

我想通过点击画布来移动一只乌龟,乌龟应该指向它移动的方向。移动部分可以工作,但旋转功能会导致图像变形和损坏。

我做错了什么,我该如何解决?

我有一个类可以将乌龟的图像添加到画布上:

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 个像素,然后在速度参数确定的时间延迟后重新调用自身。它还应该旋转海龟,使其指向正确的方向:

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)

四处移动可以正常工作,但是旋转功能会导致图像失真和损坏,并且每次调用都会变得更糟。

你能告诉我为什么这不起作用,我需要做什么来解决它?

这是该乌龟旋转前后的截图:

【问题讨论】:

  • 你要分享原始的乌龟图像吗?并向我们​​展示一只“畸形”乌龟的样子?
  • @MarkSetchell 我明天会编辑并上传截图

标签: python-3.x tkinter python-imaging-library


【解决方案1】:

我找到了解决方案,我必须重新打开文件:

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)

我不知道为什么。

【讨论】:

    猜你喜欢
    • 2021-09-27
    • 1970-01-01
    • 2016-01-12
    • 1970-01-01
    • 2013-07-03
    • 1970-01-01
    • 2016-08-05
    • 2021-02-14
    • 2016-03-13
    相关资源
    最近更新 更多