【问题标题】:How to reverse the y-axis of the imported image in Tkinter?如何在 Tkinter 中反转导入图像的 y 轴?
【发布时间】:2013-11-04 06:20:16
【问题描述】:

对于重复标记:我完全清楚matplotlib中存在一些类似的问题,例如this one。我的问题是关于Tkinter 而不是matplotlib

我现在将 Lena 导入 python 并在她的帽子上画一个绿点

In [72]: from PIL import Image
   ....: import matplotlib.pylab as plt
   ....: im = Image.open('lena.jpg')
   ....: fig = plt.figure()
   ....: axes = fig.add_axes([0.1, 0.1, 0.8, 0.8])
   ....: axes.imshow(im)
   ....: axes.scatter(50, 50, marker='s', color='green')
Out[72]: <matplotlib.collections.PathCollection at 0xb3e2ef0>

(请忽略红点)

我现在希望绿点 (50, 50) 仍在 Lena 的帽子上,但我还希望将绿点绘制在左下角而不是左上角。

我希望是这样的:

正如所见,我设法在matplotlib 中轻松地做到了这一点,并增加了一行:

axes.invert_yaxis()

问题

我现在在Tkinter 的画布上绘图。 我怎样才能达到同样的效果?


更新

Lena 只是为了说明我的目的。在我真正的问题中,我没有在Tkinter 中导入任何内容。我只是在空白画布上作画。我不愿意修改我的数据,我只想把绘图颠倒过来。就像在我的 Lena 插图中,坐标仍然是 (50, 50)。不同的是现在它在左下角而不是上角。

【问题讨论】:

  • 您能出示您的 Tkinter 代码吗?
  • @falsetru 我的代码很乱。但是我想我已经说清楚了,尽管我只使用了描述。您可以将我的代码视为在画布上绘制一个点,这非常简单。现在我希望我的左下角是 (0, 0)

标签: python tkinter


【解决方案1】:

角度可以这样使用:

image = Image.open("lena.jpg")
angle = 180
tkimage = ImageTk.PhotoImage(image.rotate(angle))
...

可以绘制图片,并使用反转坐标(因此,当您知道画布的大小时,可以使用50x50,而不是(max-50)x(max-50)

问题是axes.imshow 是否可以处理ImageTk.PhotoImage。再说一次,我不完全确定您是否只想在 Tkinter 画布上使用它,例如:

canvas_obj = self.canvas.create_image(250, 250, image=tkimage)

【讨论】:

  • 哦,Lena 只是为了说明我的目的。在我真正的问题中,我没有在 Tkinter 中导入任何东西。我只是在空的画布上画画。我不愿意修改我的数据,我只想把图纸倒过来。
  • @mavErick 所以问题是反转画布?或者反过来画也可以(然后你用(max-50)画出50的倒数)?
  • 我认为反向绘制就可以,但正如我所说,我真的不愿意专门为绘图修改我的数据点。
  • 你画什么?目的是什么?您可以先将这些点保存到一个文件中,然后再重新加载和反转吗?我认为不可能按照您描述的方式旋转画布。
【解决方案2】:

在我看来,使用下面的代码会很简单:

import Tkinter
#Set up a basic canvas
top = Tkinter.Tk()
canv = Tkinter.Canvas(top, bg="brown", height=250, width=300)

#Replace with what ever values you want
x = 50
y = 50

#Draw the first dot
line1 = canv.create_line(x, y, x - 2, y - 2, fill="green", width=3)
#This next line is pretty much all it takes to find the Y inverse
y = canv.winfo_reqheight() - y
#Draw the second dot
line2 = canv.create_line(x, y, x - 2, y - 2, fill="green", width = 3)

canv.pack()
top.mainloop()

这将返回以下内容:

基本上我所做的只是获取画布高度 (250),然后从中减去之前的 Y 值 (50),返回 Y 倒数 (200)。不完全是内置功能,但实际的翻转部分非常简单。希望这就是您要找的...祝您好运!

【讨论】:

    【解决方案3】:

    您似乎要求的是 2D 世界到视口的转换:

    以“世界坐标”定义的区域(例如 10 米乘 10 米) 并将其映射到画布坐标中定义的区域。

    例如。

    from tkinter import *
    
    xmin,ymin,xmax,ymax = 0,0,10,10   # world
    umin,vmin,umax,vmax = 0,480,640,0 # viewport (note: y reversed)
    
    points = [(2,2), (4,4), (7,7), (8,8)]  # some "world" points
    
    def world_to_viewport(worldpoint):
        x,y = worldpoint
        u = (x - xmin)*((umax - umin)/(xmax - xmin)) + umin
        v = (y - ymin)*((vmax - vmin)/(ymax - ymin)) + vmin
        return u,v
    
    def pixel_to_world(pixel):
        u,v = pixel
        x = (u - umin)*((xmax - xmin)/(umax - umin)) + xmin
        y = (v - vmin)*((ymax - ymin)/(vmax - vmin)) + ymin
        return x,y
    
    root = Tk()
    canvas = Canvas(root, width=640, height=480, bd=0, highlightthickness=0)
    canvas.pack()
    
    def on_click(event):
        root.title('%s,%s' %(pixel_to_world((event.x,event.y))))
    
    canvas.bind('<ButtonPress-1>', on_click)
    
    r = 5
    for point in points:
        cx,cy = world_to_viewport(point)
        canvas.create_oval(cx-r,cy-r,cx+r,cy+r,fill='red')
    
    root.mainloop()
    

    【讨论】:

      猜你喜欢
      • 2019-11-03
      • 1970-01-01
      • 1970-01-01
      • 2017-12-07
      • 2022-07-07
      • 1970-01-01
      • 2022-08-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多