質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

Q&A

0回答

1100閲覧

tkinterによる画像の拡大

tete12

総合スコア0

Tkinter

Tkinterは、GUIツールキットである“Tk”をPythonから利用できるようにした標準ライブラリである。

0グッド

0クリップ

投稿2021/10/16 17:21

前提・実現したいこと

tkinterを用いて、画像をマウスに重ねマウスホイールを回すことで画像の大きさが
変化するGUIを作ろうと思っています。

発生している問題・エラーメッセージ

一枚の画像の拡大縮小はできたのですが、複数の画像を添付し張り付けるコードがわかりません。

該当のソースコード

python

1import tkinter 2from PIL import Image, ImageTk 3import time 4import math 5 6# 読み込む画像へのファイルパス設定 7 8IMAGE_PATH = "image.png" 9 10# キャンバスのサイズ設定 11CANVAS_WIDTH = 600 12CANVAS_HEIGHT = 400 13 14class ImageZoom(): 15 ###'''画像拡大縮小アプリ''' 16 17 def __init__(self, master): 18 self.master = master 19 20 # 画像の読み込み 21 self.image = Image.open(IMAGE_PATH) 22 23 # キャンバスのサイズ設定 24 self.canvas_width, self.canvas_height = CANVAS_WIDTH, CANVAS_HEIGHT 25 26 # 表示する画像の設定 27 self.draw_image = None 28 self.tk_image = None 29 30 # ウィジェットの作成と配置 31 self.create_widgets() 32 33 # イベント設定 34 self.set_events() 35 36 # キャンバスサイズに合わせて画像の拡大率決定 37 self.ratio = min( 38 self.canvas_width / self.image.width, 39 self.canvas_height / self.image.height 40 ) 41 42 # 画像の表示 43 self.resize(self.ratio) 44 45 # 画像の描画 46 self.draw() 47 48 def create_widgets(self): 49 ### '''ウィジェットを作成する''' 50 51 # キャンバス作成 52 self.canvas = tkinter.Canvas( 53 self.master, 54 width = self.canvas_width, 55 height = self.canvas_height, 56 highlightthickness=0 57 ) 58 self.canvas.pack() 59 60 def draw(self): 61 ###'''キャンバスの中心に画像を描画する''' 62 63 # tkinter画像オブジェクトに変換 64 self.tk_image = ImageTk.PhotoImage(self.draw_image) 65 66 # キャンバスに画像を描画 67 self.canvas.create_image( 68 self.canvas_width // 2, self.canvas_height // 2, 69 anchor=tkinter.CENTER, 70 image=self.tk_image 71 ) 72 73 def set_events(self): 74 ###'''イベントの設定を行う''' 75 76 # マウスホイールイベントを設定 77 self.canvas.bind("<MouseWheel>", self.event_handler) 78 79 # Linux の場合は下記で設定できる? 80 # self.canvas.bind("<ButtonPress-4>", self.event_handler) 81 # self.canvas.bind("<ButtonPress-5>", self.event_handler) 82 83 84 def unset_events(self): 85 ###'''イベント設定の取り消し''' 86 87 # マウスホイールイベント取り消し 88 self.canvas.unbind("<MouseWheel>") 89 90 # Linux の場合は下記で取り消しできる? 91 # self.canvas.bind("<ButtonPress-4>" 92 # self.canvas.bind("<ButtonPress-5>") 93 94 def event_handler(self, event): 95 ###'''マウスホイールイベント発生時の処理''' 96 97 # マウスホイール(トラックパッド)の動きに合わせて拡大率設定 98 self.ratio = self.ratio * (100 + (event.delta / 120)) / 100 99 100 # 拡大率の下限と上限を設定 101 if self.ratio < 0.01: 102 self.ratio = 0.01 103 if self.ratio > 100: 104 self.ratio = 100 105 106 # リサイズ 107 self.resize(self.ratio) 108 109 # 画像の描画 110 self.draw() 111 112 # 一旦イベント受付終了 113 self.unset_events() 114 115 # 少しディレイを入れてイベント再受付 116 self.master.after(10, self.set_events) 117 118 def resize(self, ratio): 119 ###'''画像のリサイズを行う''' 120 121 start = time.time() 122 123 # リサイズ後画像サイズを算出 124 resized_width = self.image.width * self.ratio 125 resized_height = self.image.height * self.ratio 126 127 # リサイズ後画像サイズが0の場合は1に設定 128 if resized_width < 1: 129 resized_width = 1 130 131 if resized_height < 1: 132 resized_height = 1 133 134 # クロップする領域を決定していく 135 sx = 0 136 sy = 0 137 ex = resized_width - 1 138 ey = resized_height - 1 139 140 if resized_width > self.canvas_width: 141 142 # はみ出る場合はリサイズ後にキャンバスからはみ出ないようにリサイズ前にクロップ 143 sx = (resized_width - self.canvas_width) / 2 144 ex = sx + self.canvas_width 145 146 if resized_height > self.canvas_height: 147 148 # はみ出る場合はリサイズ後にキャンバスからはみ出ないようにリサイズ前にクロップ 149 sy = (resized_height - self.canvas_height) / 2 150 ey = sy + self.canvas_height 151 152 # リサイズ後にキャンバスからはみ出ない領域の矩形を設定 153 crop_size = ( 154 math.floor(sx / self.ratio), 155 math.floor(sy / self.ratio), 156 math.ceil(ex / self.ratio), 157 math.ceil(ey / self.ratio) 158 ) 159 160 # クロップ 161 crop_image = self.image.crop(crop_size) 162 163 # キャンバスに描画する画像のサイズを設定 164 draw_width = int(self.ratio * crop_image.width) 165 draw_height = int(self.ratio * crop_image.height) 166 167 # 画像をリサイズ 168 self.draw_image = crop_image.resize( 169 (draw_width, draw_height), 170 Image.BILINEAR 171 ) 172 173 end = time.time() 174 ### print("拡大率" + str(self.ratio) + "のリサイズ時間:" + str(end - start)) 175 176def main(): 177 app = tkinter.Tk() 178 iz = ImageZoom(app) 179 app.mainloop() 180 181main()

試したこと

classの中でfor文でimage_pathを変えましたが、画像が一枚しか添付できませんでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問