いくつか改良を加えました。大きな改良は,左ボタンをを押したままにすると,動作?が続くようにしたこと
です。いままでは,一端ボタンを離して再びクリックしないと,同じ動作の繰り返しができませんでしたが,
改良いたしました。ある方のプログラムをおかりしてます。考え方としては,PICでよく使った割り込み処理
と同じ方法のようです。
クリックである動作(一回実施)
ボタンを離すとある動作
の動作は比較的簡単にできるのですが,
クリックである動作を続ける(クリックされている間繰り返して行う)
ボタンを離すと上記の動作をやめる。
ができなかったので大助かりでした。
それと,一定の角度の開きで回転する部分を,開き方を調整できるようにしたこと,回転角度を指定できるよ
うにしたことです。
これで,表示部分は,ほぼ完成ですが,「回転」→→「開く」の切り替え時に,がうまくいかないのが課題で
どうしようかと思案してます。
以下が,プログラムの全文です。
# ライブラリのインポート
import cv2
#import tkinter as tk
#impor tk.filedialog, tk.messagebox
import tkinter, tkinter.filedialog, tkinter.messagebox
from PIL import Image, ImageTk
import os
import matplotlib.pyplot as plt
import numpy as np
import time
dt=100 # millisecond
class SpecialButton(tkinter.Button):
#def activate_press_and_release(self):
def __init__(self,*args,**kwargs):
#tk.Button.__init__(self,*args,**kwargs)
tkinter.Button.__init__(self,*args,**kwargs)
self._is_pressed = False
self.bind('',self.pressed)
self.bind('',self.released)
def pressed(self,value):
self._is_pressed = True
def released(self,value):
self._is_pressed = False
# ファイル名を配列に格納
file_names = ['00.jpg', '01.jpg', '02.jpg','03.jpg','04.jpg','05.jpg','06.jpg','07.jpg','08.jpg','09.jpg','10.jpg',\
'11.jpg','12.jpg','13.jpg','14.jpg','15.jpg','16.jpg','17.jpg','18.jpg','19.jpg','20.jpg','21.jpg',\
'22.jpg','23.jpg','24.jpg','25.jpg','26.jpg','27.jpg','28.jpg','29.jpg','30.jpg','31.jpg','32.jpg',\
'33.jpg','34.jpg','35.jpg','36.jpg','37.jpg','38.jpg','39.jpg','40.jpg','41.jpg','42.jpg','43.jpg',\
'44.jpg','45.jpg','46.jpg','47.jpg','48.jpg','49.jpg','50.jpg','51.jpg','52.jpg','53.jpg','54.jpg',\
'55.jpg','56.jpg','57.jpg','58.jpg','59.jpg','60.jpg','61.jpg','62.jpg','63.jpg','64.jpg','65.jpg']
file_names1 = [ '0.jpg', '1.jpg', '2.jpg','3.jpg','4.jpg','5.jpg','6.jpg','7.jpg','8.jpg','9.jpg','10.jpg',\
'11.jpg','12.jpg','13.jpg','14.jpg','15.jpg','16.jpg','17.jpg','18.jpg','19.jpg','20.jpg','21.jpg',\
'22.jpg','23.jpg','24.jpg','25.jpg','26.jpg','27.jpg','28.jpg','29.jpg','30.jpg','31.jpg','32.jpg',\
'33.jpg','34.jpg','35.jpg','36.jpg','37.jpg','38.jpg','39.jpg','40.jpg','41.jpg','42.jpg','43.jpg',\
'44.jpg','45.jpg','46.jpg','47.jpg','48.jpg','49.jpg','50.jpg','51.jpg','52.jpg','53.jpg','54.jpg',\
'55.jpg','56.jpg','57.jpg','58.jpg','59.jpg','60.jpg']
#グローバル変数の定期
img=file_names[0]
kaisu=0
kaisu1=0
gazou=""
img1=""
revers=0
kaiten_deg=0
kaiten_ang=0
cw_f=0
ccw_f=0
button_f=0
dt=100
imagetk_list = list()
# ベースパスを設定
base_path = 'E:/python-kaihatu/nanikana/mask-jp'
base_path1 = 'E:/python-kaihatu/nanikana/mask-r1'
# tkオブジェクトの作成
root = tkinter.Tk()
root.title("なにかな") #ウィンドウのタイトルを設定
root.geometry("700x570") #ウィンドウのサイズを設定
### キャンバス作成
canvas=tkinter.Canvas(root,width=550, height=550)
canvas.place(x = 10,y = 10)
#背景画像を読み込み
gazou= cv2.imread('E:/python-kaihatu/nanikana/gazou/isu.jpg')
def gazou_over():
global kaisu,gazou
# 「フルパス+ファイル名」を作成
full_path = os.path.join(base_path, file_names[kaisu])
# マスクファイルを開く
mask = cv2.imread(full_path)
if mask is not None:
#画像の合成
result = cv2.bitwise_and(mask,gazou)
#BRG読み込みをRGBに変換
result = cv2.cvtColor(result, cv2.COLOR_BGR2RGB)
#フォーマットをPILに変換
result = Image.fromarray(result)
return result
def kaiten_mr():
global result1,mask,kaiten_deg,kaiten_ang
# フルパスを作成
full_path = os.path.join(base_path,file_names[kaisu1] )
# マスクファイルを開く
mask = cv2.imread(full_path)
#マスク画像の回転
# 高さ・幅・回転の中心定義
height = mask.shape[0]
width = mask.shape[1]
center = (int(width/2), int(height/2))
angle = kaiten_deg*kaiten_ang*(-1)
scale=1.0
trans = cv2.getRotationMatrix2D(center, angle , scale)
mask = cv2.warpAffine(mask, trans, (width,height), borderMode=cv2.BORDER_CONSTANT, borderValue=(255, 255, 255))
#画像の合成
result1 = cv2.bitwise_and(mask,gazou)
#BRG読み込みをRGBに変換
result1= cv2.cvtColor(result1, cv2.COLOR_BGR2RGB)
#フォーマットをPILに変換
result1 = Image.fromarray(result1)
#TkinterのPhotoImageに変換
result1=ImageTk.PhotoImage(result1)
canvas.create_image(273,273,image = result1,tag='p1')
def kaiten():
global result1,mask
# フルパスを作成
full_path1 = os.path.join(base_path1, file_names1[kaisu1])
# マスクファイルを開く
mask = cv2.imread(full_path1)
#画像の合成
result1 = cv2.bitwise_and(mask,gazou)
#cv2.imshow('test', result)
#BRG読み込みをRGBに変換
result1= cv2.cvtColor(result1, cv2.COLOR_BGR2RGB)
#フォーマットをPILに変換
result1 = Image.fromarray(result1)
#TkinterのPhotoImageに変換
result1=ImageTk.PhotoImage(result1)
canvas.create_image(273,273,image = result1,tag='p1')
#クリック動作
def on_button_click():
global kaisu,imagetk_list,button_f
button_f=1
if kaisu<65:
kaisu= kaisu+1
#旧画像の削除
canvas.delete('p1')
result= gazou_over()
result=ImageTk.PhotoImage(result)
imagetk_list.append(result)
canvas.create_image(273,273,image = result,tag='p1')
def on_button1_click():
global kaisu,imagetk_list,button_f
if kaisu>0:
kaisu= kaisu-1
#旧画像の削除
canvas.delete('p1')
result= gazou_over()
result=ImageTk.PhotoImage(result)
imagetk_list.append(result)
canvas.create_image(273,273,image = result,tag='p1')
def on_button2_click():
global kaisu1,kaiten_deg,cw_f,ccw_f,kaiten_ang
kaisu1=int(textbox1.get())
kaiten_ang=int(textbox2.get())
cw_f=1#時計回り回転
if ccw_f==1:
ccw_f=0
kaiten_deg=kaiten_deg+2
if kaiten_deg==0:
kaiten_mr()
kaiten_deg=kaiten_deg+1
else:
kaiten_mr()
kaiten_deg=kaiten_deg+1
def on_button3_click():
global kaisu1,kaiten_deg,cw_f,ccw_f,kaiten_ang
kaisu1=int(textbox1.get())
kaiten_ang=int(textbox2.get())
ccw_f=1#逆時計回り回転
if cw_f==1:
cw_f=0
kaiten_deg=kaiten_deg-2
if kaiten_deg==0:
kaiten_deg=kaiten_deg-1
kaiten_mr()
kaiten_deg=kaiten_deg-1
else:
kaiten_mr()
kaiten_deg=kaiten_deg-1
def on_button4_click():
global gazou
fTyp = [("","*")]
#iDir = os.path.abspath(os.path.dirname(__file__))
iDir='E:/python-kaihatu/nanikana/gazou/'
tkinter.messagebox.showinfo('なにかな','処理ファイルを選択してください!')
file = tkinter.filedialog.askopenfilename(filetypes = fTyp,initialdir = iDir)
# 処理ファイル名の出力
#tkinter.messagebox.showinfo('なにかな',file)
if file=="":
gazou=cv2.imread('E:/python-kaihatu/nanikana/gazou/isu.jpg')
else:
gazou=cv2.imread(file)
img_pil=gazou_over()
img_pil=ImageTk.PhotoImage(img_pil)
#画像ファイルをキャンバスの(0,0)に合わせて表示してみる
canvas.create_image(273,273,image = img_pil,tag='p1')
def on_button5_click():
global kaisu1,kaiten_deg
kaisu1=4
kaiten_mr()
kaiten_deg=kaiten_deg+1
def callback():
global root,button1,button2
if button._is_pressed:
on_button_click()
if button1._is_pressed:
on_button1_click()
if button2._is_pressed:
on_button2_click()
if button3._is_pressed:
on_button3_click()
time.sleep(0.05)
root.after(dt,callback)
#PILでjpgを使用
img_pil=gazou_over()
img_pil=ImageTk.PhotoImage(img_pil)
#画像ファイルをキャンバスの(0,0)に合わせて表示してみる
canvas.create_image(273,273,image = img_pil,tag='p1')
# ウィジェットの配置や、イベント処理などを記述
textbox1 = tkinter.Entry(root,width=3)
textbox1.place(x=635, y=230)
textbox1.insert(0,"4")
textbox2 = tkinter.Entry(root,width=3)
textbox2.place(x=635, y=250)
textbox2.insert(0,"5")
#button = tkinter.Button(root, text="cw開く", bg="cyan4", fg="white",width=8, height=1,)
button = SpecialButton(text="cw開く", bg="cyan4", fg="white",width=8, height=1,)
button.place(x=595, y=30)
button1 = SpecialButton(text="ccw閉じる", command=on_button1_click, bg="cyan4", fg="white",width=8, height=1)
button1.place(x=595, y=60)
button2 = SpecialButton(text="回転", command=on_button2_click, bg="cyan4", fg="white",width=8, height=1)
button2.place(x=595, y=170)
button3 = SpecialButton(text="逆回転", command=on_button3_click, bg="cyan4", fg="white",width=8, height=1)
button3.place(x=595, y=200)
button4 = tkinter.Button(root,text="ファイル", command=on_button4_click, bg="cyan4", fg="white",width=8, height=1)
button4.place(x=595, y=400)
# メインループの実行
#root = tkinter.Tk()
root.after(dt,callback)
root.mainloop()
今回の目玉は,tkinter.Button の代わりに諸兄の作られた SpecialButton のを使ったことと,下記の
callback()
関数を使ったことです。この関数は,一定時間間隔で,自分自身を呼び出す,「再帰」を使っていることで
す。今回のプログラムを考えるにあたって,左ボタンのチェックを,無限ループのなかで,チェックして,
フラグによって,ループを抜ける方法もやってみましたが,うまく動作しませんでした。またしても,諸兄
に助けられました,それにしても,すごい方がいるもんです。
def callback():
global root,button1,button2
if button._is_pressed:
on_button_click()
if button1._is_pressed:
on_button1_click()
if button2._is_pressed:
on_button2_click()
if button3._is_pressed:
on_button3_click()
time.sleep(0.05)
root.after(dt,callback)