2011-03-31 247 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