放大和缩小PIL图像

问题描述 投票:0回答:1

即使我在 xview 中使用拖动,如何才能使图像始终位于窗口中间?这是代码:

from tkinter import *
from tkinter import ttk
from PIL import Image, ImageTk
import tkinter as tk

root = Tk()
root.minsize(height=650, width=1350)
root.title('Image Viewer')

frame=ttk.Frame(root,width=700,height=600)
frame.pack(expand=False, fill=BOTH) 

btn_1 = ttk.Button(root, text = 'Next')
btn_1.pack(side = RIGHT, padx = 15, pady = 10)

btn_2 = ttk.Button(root, text = 'Previous')
btn_2.pack(side = LEFT, padx = 15, pady = 10)

canvas=tk.Canvas(frame,bg='#FFFFFF',width=479,height=600)
canvas.configure(scrollregion=canvas.bbox('all'))
canvas.pack(expand=True,fill=BOTH)

lbl_1 = ttk.Label(root, text = 'First image', style='BW.TLabel')
lbl_1.pack(side = TOP, pady = 5)

def resize(image2, new_width):
    width, height = img.size
    ratio = height/width
    new_height = int(ratio*new_width)
    res_img = img.resize((new_width,new_height))
    return res_img

img = Image.open("C:\\Users\\Administrateur\\Desktop\\pyth\\1.jpg")
res_img= resize(img, 479)
img_tk = ImageTk.PhotoImage(res_img)

canvas_image_id=canvas.create_image (435.5, 0, anchor=tk.NW, image=img_tk)

zoom_level = 100

def zoom(event):
    global res_img, img_tk, zoom_level, canvas_image_id, canvas

    factor = 1.2
    if event.delta > 0: 
        if (zoom_level *  factor)  > 600: return
        zoom_level *= factor
                        
    else:
        if (zoom_level /  factor)  < 100: return 
        zoom_level /= factor
                              
    def on_move_from(event):
        if zoom_level > 300:
            canvas.scan_mark(event.x, event.y)
        elif zoom_level > 100:
            canvas.scan_mark(canvas_x, event.y)
        else: 
            return

    def on_mouse_drag(event):
        if zoom_level > 300:
            canvas.scan_dragto(event.x, event.y, gain=1) 
        elif zoom_level > 100:
            canvas.scan_dragto(canvas_x, event.y, gain=1)
        else:
            return
                    
    if zoom_level > 100:
        canvas.bind('<ButtonPress-1>', on_move_from)
        canvas.bind("<B1-Motion>", on_mouse_drag)
    else :
        return

    new_width = int(res_img.width * (zoom_level / 100)) 
    new_height = int(res_img.height * (zoom_level / 100)) 

    canvas_x = canvas.winfo_width()//2
    canvas_y = canvas.winfo_height() // 2

    x0 = canvas_x - int(new_width / 2) 
    y0 = canvas_y - int(new_height / 2) 
    x1 = canvas_x + int(new_width / 2) 
    y1 = canvas_y + int(new_height / 2) 

    resized_image = res_img.resize((new_width, new_height), Image.Resampling.LANCZOS)
    img_tk = ImageTk.PhotoImage(resized_image)
    
    canvas.coords(canvas_image_id, x0, y0)
    canvas.itemconfig(canvas_image_id, image=img_tk)
    canvas.configure(scrollregion=canvas.bbox('all'))

canvas.bind("<MouseWheel>", zoom)                   
                   

如果我放大而不移动 x 中的图像,那么当我缩小时,一切都是完美的,但是如果我在 x 中移动图像,同时它的大小调整得更大,那么如果我缩小图像,图像就会显得另类。那么,即使我在 xview 中使用拖动,如何才能使图像始终位于窗口中间?

python tkinter drag-and-drop zooming
1个回答
0
投票

要解决这个问题,只需将 canvas.canvasx 与 x0, y0 , x1 , y1 一起放置即可。

x0 = canvas.canvasx(canvas_x - int(new_width / 2)) 
y0 = canvas.canvasy(canvas_y - int(new_height / 2)) 
x1 = canvas.canvasx(canvas_x + int(new_width / 2))
y1 = canvas.canvasy(canvas_y + int(new_height / 2))
© www.soinside.com 2019 - 2024. All rights reserved.