Hinzufügen von Zoom-in und Zoom-out mit einem Tkinter-Canvas-Widget?
Wie sollte ich hinzufügen, ein-und Auszoomen, um das folgende Skript, möchte ich binden Sie es auf das Mausrad. Wenn Sie testen dieses Skript auf linux vergessen Sie nicht, ändern Sie das MouseWheel-Ereignis-Taste-4 und Taste-5.
from Tkinter import *
import Image, ImageTk
class GUI:
def __init__(self,root):
frame = Frame(root, bd=2, relief=SUNKEN)
frame.grid_rowconfigure(0, weight=1)
frame.grid_columnconfigure(0, weight=1)
xscrollbar = Scrollbar(frame, orient=HORIZONTAL)
xscrollbar.grid(row=1, column=0, sticky=E+W)
yscrollbar = Scrollbar(frame)
yscrollbar.grid(row=0, column=1, sticky=N+S)
self.canvas = Canvas(frame, bd=0, xscrollcommand=xscrollbar.set, yscrollcommand=yscrollbar.set, xscrollincrement = 10, yscrollincrement = 10)
self.canvas.grid(row=0, column=0, sticky=N+S+E+W)
File = "PATH TO JPG PICTURE HERE"
self.img = ImageTk.PhotoImage(Image.open(File))
self.canvas.create_image(0,0,image=self.img, anchor="nw")
self.canvas.config(scrollregion=self.canvas.bbox(ALL))
xscrollbar.config(command=self.canvas.xview)
yscrollbar.config(command=self.canvas.yview)
frame.pack()
self.canvas.bind("<Button 3>",self.grab)
self.canvas.bind("<B3-Motion>",self.drag)
root.bind("<MouseWheel>",self.zoom)
def grab(self,event):
self._y = event.y
self._x = event.x
def drag(self,event):
if (self._y-event.y < 0): self.canvas.yview("scroll",-1,"units")
elif (self._y-event.y > 0): self.canvas.yview("scroll",1,"units")
if (self._x-event.x < 0): self.canvas.xview("scroll",-1,"units")
elif (self._x-event.x > 0): self.canvas.xview("scroll",1,"units")
self._x = event.x
self._y = event.y
def zoom(self,event):
if event.delta>0: print "ZOOM IN!"
elif event.delta<0: print "ZOOM OUT!"
root = Tk()
GUI(root)
root.mainloop()
Sind Sie eigentlich auf der Suche skalieren", um die Leinwand oder nur das Bild?
alles, was auf der Leinwand, das Bild und eine Auswahl von Linien und Kreisen auf der Leinwand schließlich. Und einmal platziert, ist es unglaublich wichtig, dass alles hält die x -, y-Koordinaten.
alles, was auf der Leinwand, das Bild und eine Auswahl von Linien und Kreisen auf der Leinwand schließlich. Und einmal platziert, ist es unglaublich wichtig, dass alles hält die x -, y-Koordinaten.
InformationsquelleAutor Symon | 2011-03-25
Du musst angemeldet sein, um einen Kommentar abzugeben.
Meines Wissens die integrierte Tkinter-Canvas-Klasse-Skala wird nicht die auto-Skalierung von Bildern. Wenn Sie nicht mit einem benutzerdefinierten widget, können Sie die Größe des raw-Bildes, und ersetzen Sie es auf der Leinwand, wenn der Maßstab die Funktion aufgerufen wird.
Das code-snippet unten zusammengefasst werden können, in Ihrer ursprünglichen Klasse. Es führt Folgendes aus:
Image.open()
.redraw()
Funktion zur Berechnung des skalierten Bildes und fügt hinzu, dass auf der Leinwand und entfernt auch das vorher-Bild gezeichnet, wenn überhaupt.x and y
zu dencreate_image
Funktion, zu zeigen, wie das Bild Platzierung verschiebt sich herum, als die Maus bewegt wird. Sie können ersetzen Sie diese mit Ihrem eigenen center/offset-Berechnung.(Aktualisiert) Code:
Update ich habe ein bisschen von Tests auf unterschiedlichen Skalen und fand, dass Sie ziemlich viel Speicher verwendet wird, die von Größe /create_image. Ich lief den test mit einem 540x375 JPEG auf einem Mac Pro mit 32GB RAM. Hier ist der Arbeitsspeicher, der für verschiedene Skalierungsfaktoren:
Angesichts der oben genannten, eine effizientere Lösung sein könnte, um zu bestimmen, die Größe des Viewports, wo das Bild angezeigt wird, berechnen Sie ein Rechteck zum beschneiden um das Zentrum der Koordinaten der Maus, das Bild zuschneiden, mit dem rect, dann skaliert nur der beschnittene Teil. Diese sollten Konstanten-Speicher zur Speicherung der temporären Bild. Andernfalls müssen Sie möglicherweise verwenden Sie eine 3rd-party-Tkinter-Steuerung führt, die das zuschneiden /Fenster-Skalierung für Sie.
Update 2 Arbeiten, aber grob vereinfachte zuschneiden Logik, nur für den Einstieg:
du bist willkommen, schön, dass es hilft Sie Fortschritte machen. Da die Leinwand nicht automatisch die Größe von Bildern, die
redraw()
Methode tut dies manuell-Reskalierung und re-hinzufügen-das Bild auf die Leinwand. Gleichzeitig Skala beliebige Vektoren gezeichnet, auf der Leinwand (Linien, Ellipsen, Polygone) können Sie einen Anruf hinzufügen, umself.canvas.scale(ALL, x, y, self.scale, self.scale)
zu denredraw()
Methode oben.hmm, ich verwende Linux und habe nicht gesehen, dass Fehler. Ist das Bild, das Sie skalieren, wirklich große?
Es ist ein 2058x2165 211KB .jpg-Bild, ich werde sehen, ob ich kann nichts finden, auf der interwebs. Skalierung der Elemente auf der Leinwand funktioniert Super vielen Dank für das auch!
Ich aktualisierte den code mit einem einfachen zuschneiden/skalieren Beispiel, die ist sehr schnell und verwendet steter Erinnerung. Hoffentlich nützlich ist. Viel Glück mit Ihren Bemühungen!
InformationsquelleAutor samplebias
Nur für die anderen profitieren, die sich diese Frage bin ich die Befestigung meiner neer letzten test-code, welcher verwendet Bild-in-Bild/Lupe zum Zoomen. Es ist im Grunde nur eine änderung, was samplebias schon gepostet. Es ist auch sehr cool zu sehen, wie gut :).
Als ich sagte vorher, wenn Sie dieses Skript auf linux vergessen Sie nicht, ändern Sie das MouseWheel-Ereignis-Taste-4 und Taste-5. Und Sie müssen natürlich einfügen .JPG-Pfad, wo es heißt "EINFÜGEN-JPG-DATEI-PFAD".
InformationsquelleAutor Symon
Könnte eine gute Idee sein Blick auf die TkZinc widget, statt der einfachen Leinwand für das, was Sie tun, es unterstützt die Skalierung über OpenGL.
InformationsquelleAutor schlenk
InformationsquelleAutor foo bar