2011-03-31 323 views

回答

30

是的,它是可能的,很容易,一旦你理解Tkinter的,这里有一个快速脚本:

from Tkinter import * 
from tkFileDialog import askopenfilename 
import Image, ImageTk 

if __name__ == "__main__": 
    root = Tk() 

    #setting up a tkinter canvas with scrollbars 
    frame = Frame(root, bd=2, relief=SUNKEN) 
    frame.grid_rowconfigure(0, weight=1) 
    frame.grid_columnconfigure(0, weight=1) 
    xscroll = Scrollbar(frame, orient=HORIZONTAL) 
    xscroll.grid(row=1, column=0, sticky=E+W) 
    yscroll = Scrollbar(frame) 
    yscroll.grid(row=0, column=1, sticky=N+S) 
    canvas = Canvas(frame, bd=0, xscrollcommand=xscroll.set, yscrollcommand=yscroll.set) 
    canvas.grid(row=0, column=0, sticky=N+S+E+W) 
    xscroll.config(command=canvas.xview) 
    yscroll.config(command=canvas.yview) 
    frame.pack(fill=BOTH,expand=1) 

    #adding the image 
    File = askopenfilename(parent=root, initialdir="C:/",title='Choose an image.') 
    img = ImageTk.PhotoImage(Image.open(File)) 
    canvas.create_image(0,0,image=img,anchor="nw") 
    canvas.config(scrollregion=canvas.bbox(ALL)) 

    #function to be called when mouse is clicked 
    def printcoords(event): 
     #outputting x and y coords to console 
     print (event.x,event.y) 
    #mouseclick event 
    canvas.bind("<Button 1>",printcoords) 

    root.mainloop() 

未经编辑,将打印使用默认的窗口坐标系统控制台。画布小部件使得左上角为0,0点,因此您可能不得不乱用printcoords函数。要获得加载的图片维度,您可以使用canvas.bbox(ALL),并且您可能想切换到使用canvasx和canvasy coords,而不是它如何。如果你是tkinter的新手;谷歌应该能够帮助你从这里完成它:)。

+2

不应该是'从PIL import Image,ImageTk' – TheEspinosa 2016-08-01 10:56:08

1

一个很好的替代Tkinter的是在使用Python QT。您可以通过PyQTPySide来实现。

5

这是我前段时间使用wxPython和各种wxPython教程拼凑的版本。这将鼠标点击坐标打印到单独的输出窗口。 (使用Python 2.6.2,wxPython 2.8.10.1)

在底部的filepath变量中输入图像的路径。

import wx 

class MyCanvas(wx.ScrolledWindow): 
    def __init__(self, parent, id = -1, size = wx.DefaultSize, filepath = None): 
     wx.ScrolledWindow.__init__(self, parent, id, (0, 0), size=size, style=wx.SUNKEN_BORDER) 

     self.image = wx.Image(filepath) 
     self.w = self.image.GetWidth() 
     self.h = self.image.GetHeight() 
     self.bmp = wx.BitmapFromImage(self.image) 

     self.SetVirtualSize((self.w, self.h)) 
     self.SetScrollRate(20,20) 
     self.SetBackgroundColour(wx.Colour(0,0,0)) 

     self.buffer = wx.EmptyBitmap(self.w, self.h) 
     dc = wx.BufferedDC(None, self.buffer) 
     dc.SetBackground(wx.Brush(self.GetBackgroundColour())) 
     dc.Clear() 
     self.DoDrawing(dc) 

     self.Bind(wx.EVT_PAINT, self.OnPaint) 
     self.Bind(wx.EVT_LEFT_UP, self.OnClick) 

    def OnClick(self, event): 
     pos = self.CalcUnscrolledPosition(event.GetPosition()) 
     print '%d, %d' %(pos.x, pos.y) 

    def OnPaint(self, event): 
     dc = wx.BufferedPaintDC(self, self.buffer, wx.BUFFER_VIRTUAL_AREA) 

    def DoDrawing(self, dc): 
     dc.DrawBitmap(self.bmp, 0, 0) 

class MyFrame(wx.Frame): 
    def __init__(self, parent=None, id=-1, filepath = None): 
     wx.Frame.__init__(self, parent, id, title=filepath) 
     self.canvas = MyCanvas(self, -1, filepath = filepath) 

     self.canvas.SetMinSize((self.canvas.w, self.canvas.h)) 
     self.canvas.SetMaxSize((self.canvas.w, self.canvas.h)) 
     self.canvas.SetBackgroundColour(wx.Colour(0, 0, 0)) 
     vert = wx.BoxSizer(wx.VERTICAL) 
     horz = wx.BoxSizer(wx.HORIZONTAL) 
     vert.Add(horz,0, wx.EXPAND,0) 
     vert.Add(self.canvas,1,wx.EXPAND,0) 
     self.SetSizer(vert) 
     vert.Fit(self) 
     self.Layout() 

if __name__ == '__main__': 
    app = wx.App() 
    app.SetOutputWindowAttributes(title='stdout') 
    wx.InitAllImageHandlers() 

    filepath = 'ENTER FILEPATH HERE' 
    if filepath: 
     print filepath 
     myframe = MyFrame(filepath=filepath) 
     myframe.Center() 
     myframe.Show() 
     app.MainLoop() 
+0

我真的很喜欢这个!有没有放大和缩小图片的方法? – starbroken 2016-06-07 12:51:31

2

这是bigjim的答案的修订版本。它在Python 3.4+中工作(没有测试其他任何东西)。我没有打扰PIL部分,因为tkinter的PhotoImage可以处理gif和pgm,这足以演示这一点。

lambda函数处理事件(窗口)坐标和图像坐标之间的转换。

我还增加了对press和release的支持,因为我需要该特定功能。

from tkinter import * 
from tkinter.filedialog import askopenfilename 

event2canvas = lambda e, c: (c.canvasx(e.x), c.canvasy(e.y)) 

if __name__ == "__main__": 
    root = Tk() 

    #setting up a tkinter canvas with scrollbars 
    frame = Frame(root, bd=2, relief=SUNKEN) 
    frame.grid_rowconfigure(0, weight=1) 
    frame.grid_columnconfigure(0, weight=1) 
    xscroll = Scrollbar(frame, orient=HORIZONTAL) 
    xscroll.grid(row=1, column=0, sticky=E+W) 
    yscroll = Scrollbar(frame) 
    yscroll.grid(row=0, column=1, sticky=N+S) 
    canvas = Canvas(frame, bd=0, xscrollcommand=xscroll.set, yscrollcommand=yscroll.set) 
    canvas.grid(row=0, column=0, sticky=N+S+E+W) 
    xscroll.config(command=canvas.xview) 
    yscroll.config(command=canvas.yview) 
    frame.pack(fill=BOTH,expand=1) 

    #adding the image 
    File = askopenfilename(parent=root, initialdir="M:/",title='Choose an image.') 
    print("opening %s" % File) 
    img = PhotoImage(file=File) 
    canvas.create_image(0,0,image=img,anchor="nw") 
    canvas.config(scrollregion=canvas.bbox(ALL)) 

    #function to be called when mouse is clicked 
    def printcoords(event): 
     #outputting x and y coords to console 
     cx, cy = event2canvas(event, canvas) 
     print ("(%d, %d)/(%d, %d)" % (event.x,event.y,cx,cy)) 
    #mouseclick event 
    canvas.bind("<ButtonPress-1>",printcoords) 
    canvas.bind("<ButtonRelease-1>",printcoords) 

    root.mainloop() 
+0

感谢您的支持! – Richard 2017-03-03 06:33:32