前提・実現したいこと
ECサイトで用いられているような、元画像上にあるカーソル位置周辺を隣に拡大表示させるアプリケーションを作成しています。
将来的には拡大画像に対して画像処理を行ったうえで表示させたいのですが、カーソル位置周辺をその都度クロップすると動作が重くなることが想定されるため、
あらかじめ拡大された元画像を拡大画像用キャンパスに描画しておいて、表示枠内に表示する範囲画像をカーソルの動きと同期させながらスクロールさせることで対応させたいと考えております。(下図が完成イメージ)
今のところ、
- 元画像上にあるカーソルの動きに合わせて周辺をクロップさせる。
- クロップ画像を元画像の隣に拡大画像として表示させ、カーソルの動きと同期させる。
はできたのですが、カーソルの動きと同期させながら拡大画像をスクロールさせるコードの作成方法がイメージできていません。
解決方法をご存じの方がいらっしゃれば、ぜひご教授ください。
現在コード
Python3
1import tkinter as tk 2from PIL import Image, ImageTk 3from tkinter import font 4 5_squarelength = 256 6_framelength = 128 7 8class MainApplication(tk.Frame): 9 def __init__(self, master): 10 super().__init__(master) 11 self.master = master 12 self.master.geometry('1920x1080') 13 self.master.title("Image Viewer") 14 15 self.image = Image.open('任意画像') 16 self.resize_image = self.image.resize((600, 500)) 17 self.main_image = ImageTk.PhotoImage(self.resize_image) 18 19 self.create_widget() 20 21 22 def create_widget(self): 23 self.frame = tk.Frame(self.master, background='gray', width=1500, height=700) 24 self.frame.propagate(False) 25 self.frame.pack() 26 27 self.canvas1 = tk.Canvas(self.frame, width=self.resize_image.width, height=self.resize_image.height) 28 self.canvas2 = tk.Canvas(self.frame, width=_squarelength, height=_squarelength) 29 30 self.canvas1.place(x=50, y=100) 31 self.canvas2.place(x=758, y=100) 32 33 self.canvas1.create_image(0, 0, image=self.main_image, anchor=tk.NW) 34 35 canvas1にマウスが乗った場合、離れた場合のイベントをセット。 36 self.canvas1.bind('<Motion>', self.mouse_motion) 37 self.canvas1.bind('<Leave>', self.mouse_leave) 38 39 40 font = tk.font.Font(family='Arial', size=16, weight='bold') 41 image_title = tk.Label(text='元画像', bg = "gray", font=font) 42 image_title2 = tk.Label(text='拡大画像', bg = "gray", font=font) 43 44 image_title.place(x=50, y=60, anchor=tk.NW) 45 image_title2.place(x=758, y=60, anchor=tk.NW) 46 47 48 def mouse_motion(self, event): 49 マウス位置の座標を取得, 写真から切り出す座標定義 50 x = event.x 51 y = event.y 52 53 self.frame_rect(x, y) 54 self.canvas_set(x, y) 55 56 def frame_rect(self, x, y): 57 枠線描画を更新 58 self.frame_refresh() 59 self.crop_frame = (x-_framelength/2, y-_framelength/2, x+_framelength/2, y+_framelength/2) 60 self.rectframe = self.canvas1.create_rectangle(self.crop_frame, outline='#AAA', width=2, tag='rect') 61 62 def frame_refresh(self): 63 try: 64 self.canvas1.delete('rect') 65 except: 66 pass 67 68 def canvas_set(self, x, y): 69 枠線内をクロップ 70 zoom_mag = _squarelength / _framelength 71 croped = self.resize_image.crop(self.crop_frame) 72 zoom_image = croped.resize((int(croped.width*zoom_mag), int(croped.height*zoom_mag))) 73 74 ズームした画像を拡大画像canvasに入れる 75 self.image_refresh() 76 self.sub_image1 = ImageTk.PhotoImage(zoom_image) 77 self.sub_cv1 = self.canvas2.create_image(0, 0, image=self.sub_image1, anchor=tk.NW, tag='cv1') 78 79 80 def image_refresh(self): 81 try: 82 self.canvas2.delete('cv1') 83 except: 84 pass 85 86 def mouse_leave(self, event): 87 try: 88 self.canvas2.delete('cv1') 89 self.canvas1.delete('rect') 90 except: 91 pass 92 93if __name__ == '__main__': 94 root = tk.Tk() 95 app = MainApplication(master = root) 96 app.mainloop()
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/09/25 07:31