前提・実現したいこと
tkinterで作ったウィンドウに複数の画像を座標通りに張り付け
マウスイベントで拡大縮小のの機能を付けたいと思っています。
以下のコードで一枚の拡大縮小はできましたが、複数の添付の方法がわからないため質問しました。
発生している問題・エラーメッセージ
以下のコードで一枚の拡大縮小はできましたが、複数画像を座標通りに添付する方法がわからないため質問しました。
該当のソースコード
ソースコード
import tkinter
from PIL import Image, ImageTk
import time
import math
読み込む画像へのファイルパス設定
IMAGE_PATH = "gazou.jpg"
キャンバスのサイズ設定
CANVAS_WIDTH = 600
CANVAS_HEIGHT = 400
class ImageZoom():
'''画像拡大縮小アプリ'''
def __init__(self, master): self.master = master 画像の読み込み self.image = Image.open(IMAGE_PATH) キャンバスのサイズ設定 self.canvas_width, self.canvas_height = CANVAS_WIDTH, CANVAS_HEIGHT 表示する画像の設定 self.draw_image = None self.tk_image = None ウィジェットの作成と配置 self.create_widgets() イベント設定 self.set_events() キャンバスサイズに合わせて画像の拡大率決定 self.ratio = min( self.canvas_width / self.image.width, self.canvas_height / self.image.height ) 画像の表示 self.resize(self.ratio) 画像の描画 self.draw() def create_widgets(self): '''ウィジェットを作成する''' キャンバス作成 self.canvas = tkinter.Canvas( self.master, width = self.canvas_width, height = self.canvas_height, highlightthickness=0 ) self.canvas.pack() def draw(self): '''キャンバスの中心に画像を描画する''' tkinter画像オブジェクトに変換 self.tk_image = ImageTk.PhotoImage(self.draw_image) キャンバスに画像を描画 self.canvas.create_image( self.canvas_width // 2, self.canvas_height // 2, anchor=tkinter.CENTER, image=self.tk_image ) def set_events(self): '''イベントの設定を行う''' マウスホイールイベントを設定 self.canvas.bind("<MouseWheel>", self.event_handler) Linux の場合は下記で設定できる? self.canvas.bind("<ButtonPress-4>", self.event_handler) self.canvas.bind("<ButtonPress-5>", self.event_handler) def unset_events(self): '''イベント設定の取り消し''' マウスホイールイベント取り消し self.canvas.unbind("<MouseWheel>") Linux の場合は下記で取り消しできる? self.canvas.bind("<ButtonPress-4>" self.canvas.bind("<ButtonPress-5>") def event_handler(self, event): '''マウスホイールイベント発生時の処理''' マウスホイール(トラックパッド)の動きに合わせて拡大率設定 self.ratio = self.ratio * (100 + event.delta) / 100 拡大率の下限と上限を設定 if self.ratio < 0.01: self.ratio = 0.01 if self.ratio > 100: self.ratio = 100 リサイズ self.resize(self.ratio) 画像の描画 self.draw() 一旦イベント受付終了 self.unset_events() 少しディレイを入れてイベント再受付 self.master.after(10, self.set_events) def resize(self, ratio): '''画像のリサイズを行う''' start = time.time() リサイズ後画像サイズを算出 resized_width = self.image.width * self.ratio resized_height = self.image.height * self.ratio リサイズ後画像サイズが0の場合は1に設定 if resized_width < 1: resized_width = 1 if resized_height < 1: resized_height = 1 クロップする領域を決定していく sx = 0 sy = 0 ex = resized_width - 1 ey = resized_height - 1 if resized_width > self.canvas_width: はみ出る場合はリサイズ後にキャンバスからはみ出ないようにリサイズ前にクロップ sx = (resized_width - self.canvas_width) / 2 ex = sx + self.canvas_width if resized_height > self.canvas_height: はみ出る場合はリサイズ後にキャンバスからはみ出ないようにリサイズ前にクロップ sy = (resized_height - self.canvas_height) / 2 ey = sy + self.canvas_height リサイズ後後にキャンバスからはみ出ない領域の矩形を設定 crop_size = ( math.floor(sx / self.ratio), math.floor(sy / self.ratio), math.ceil(ex / self.ratio), math.ceil(ey / self.ratio) ) クロップ crop_image = self.image.crop(crop_size) キャンバスに描画する画像のサイズを設定 draw_width = int(self.ratio * crop_image.width) draw_height = int(self.ratio * crop_image.height) 画像をリサイズ self.draw_image = crop_image.resize( (draw_width, draw_height), Image.BILINEAR ) end = time.time()
def main():
app = tkinter.Tk()
iz = ImageZoom(app)
app.mainloop()
main()
あなたの回答
tips
プレビュー