Как повернуть и изменить размеры изображения в tkinter
Одна из функций кнопок должна поворачивать изображение,
а другая уменьшать/увеличивать размер изображения.
Как это реализовать в tkinter ?
main.py:
from tkinter import *
import PIL, os
from PIL import ImageTk, Image
while True:
try:
distanation = input('input pic dist>>>')
if distanation == 'break':
os.abort()
pil_image = Image.open(distanation)
except:
print('cant find')
else:
input()
break
#window options
window = Tk()
window.title('picture viewer(v0.14alpha)')
window.geometry('800x600')
window['bg'] = 'grey44'
for i in range(3):
window.columnconfigure(i, weight=1, minsize=70)
window.rowconfigure(i, weight=1, minsize=70)
#img
pil_image = pil_image.resize((700, 500), Image.ANTIALIAS)
pil_image.resize((18, 18))
image = ImageTk.PhotoImage(pil_image)
image_sprite = Label(window, image=image)
image_sprite.grid(row=1, column=1, padx=8)
label_pic_name = Label(window, text=distanation, fg='#ccc', bg='#555', font='Arial 14')
label_pic_name.grid(row=2, column=1)
#bottons_top
frame_top = Frame(window, width=100, height=100)
frame_top.grid(row=0, column=1)
btn1 = Button(frame_top, text="1111",
background="#555",
foreground="#ccc",
activebackground='#557',
font="16",
relief = FLAT
)
btn1.grid(row=0, column=1)
btn2 = Button(frame_top, text="2222",
background="#555",
foreground="#ccc",
activebackground='#557',
font="16",
relief = FLAT
)
btn2.grid(row=0, column=2)
btn3 = Button(frame_top, text="3333",
background="#555",
foreground="#ccc",
activebackground='#557',
font="16",
relief = FLAT
)
btn3.grid(row=0, column=3)
btn4 = Button(frame_top, text="4444",
background="#555",
foreground="#ccc",
activebackground='#557',
font="16",
relief = FLAT
)
btn4.grid(row=0, column=4)
#bottons_side
frame_side = Frame(window)
frame_side.grid(row=1, column=0, padx=10)
btn11 = Button(frame_side, text="1111",
background="#555",
foreground="#ccc",
activebackground='#557',
font="16",
relief = FLAT
)
btn11.grid(row=1, column=0)
btn22 = Button(frame_side, text="2222",
background="#555",
foreground="#ccc",
activebackground='#557',
font="16",
relief = FLAT
)
btn22.grid(row=2, column=0)
btn33 = Button(frame_side, text="3333",
background="#555",
foreground="#ccc",
activebackground='#557',
font="16",
relief = FLAT
)
btn33.grid(row=3, column=0)
btn44 = Button(frame_side, text="4444",
background="#555",
foreground="#ccc",
activebackground='#557',
font="16",
relief = FLAT
)
btn44.grid(row=4, column=0)
#functions
#def fbtn1:
#def fbtn2:
#def fbtn3:
#def fbtn4:
#def fbtn11:
#def fbtn22:
#def fbtn33:
#def fbtn44:
window.mainloop()
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Я не сильно занимался оптимизацией и отладкой, но основные моменты реализации - определил.
Установите стартовое изображение
# vvvvvvvvv
app = SimpleApp(root, 'lena2.png')
и попробуйте.
main.py
from tkinter import *
from tkinter import filedialog
from PIL import ImageTk
from PIL import Image
class SimpleApp(object):
def __init__(self, master, filename, **kwargs):
self.master = master
self.filename = filename
self.pathToImage = ''
self.canvas_obj = None
for i in range(3):
master.columnconfigure(i, weight=1, minsize=70)
master.rowconfigure(i, weight=1, minsize=70)
self.label_pic_name = Label(self.master, text=self.filename,
fg='#ccc', bg='#555', font='Arial 14')
self.label_pic_name.grid(row=2, column=1)
# bottons_top ----------------------------------------
frame_top = Frame(self.master, width=100, height=100)
frame_top.grid(row=0, column=1)
btn1 = Button(frame_top, text="+", background="#555",
foreground="#ccc", activebackground='#557',
font="16", width = 5, relief = FLAT,
command=self.enlarge_image
)
btn1.grid(row=0, column=1)
btn2 = Button(frame_top, text="-", background="#555",
foreground="#ccc", activebackground='#557',
font="16", width = 5, relief = FLAT,
command=self.reduce_image
)
btn2.grid(row=0, column=2, padx=1, pady=0)
btn3 = Button(frame_top, text="3333", background="#555",
foreground="#ccc", activebackground='#557',
font="16", width = 5, relief = FLAT
)
btn3.grid(row=0, column=3)
btn4 = Button(frame_top, text="4444", background="#555",
foreground="#ccc", activebackground='#557',
font="16", width = 5, relief = FLAT
)
btn4.grid(row=0, column=4, padx=1)
# bottons_side ------------------------------------------
frame_side = Frame(self.master)
frame_side.grid(row=1, column=0, padx=10)
btn11 = Button(frame_side, text=" << ", background="#555",
foreground="#ccc", activebackground='#557',
font="16", width=5, relief=FLAT,
command=self.image_counter_clockwise
)
btn11.grid(row=1, column=0)
btn22 = Button(frame_side, text=" >> ", background="#555",
foreground="#ccc", activebackground='#557',
font="16", width = 5, relief = FLAT,
command=self.image_clockwise
)
btn22.grid(row=2, column=0, pady=1)
btn33 = Button(frame_side, text="3333", background="#555",
foreground="#ccc", activebackground='#557',
font="16", width = 5, relief = FLAT
)
btn33.grid(row=3, column=0)
btn44 = Button(frame_side, text="4444", background="#555",
foreground="#ccc", activebackground='#557',
font="16", width = 5, relief = FLAT
)
btn44.grid(row=4, column=0, pady=1)
# butSelect ------------------------------------------
butSelect = Button(self.master,
text='Select PNG', command=self.but_select)
butSelect.grid(row=3, column=1)
self.canvas = Canvas(master,
width=700, height=500, bg="#707070", highlightthickness=0)
self.tkimage = Image.open(self.filename)
self.canvas.grid(row=1, column=1,
padx=10, pady=10,
ipadx=0, ipady=0,
)
self.update = self.draw(number_cycles=38).__next__
master.after(500, self.update)
# draw ------------------------------------------
def draw(self, number_cycles=0):
image = Image.open(self.filename)
angle = 0
i = 0
flag = True
while flag:
i += 1
if i < number_cycles:
tkimage = ImageTk.PhotoImage(image.rotate(angle))
self.canvas_obj = self.canvas.create_image(
350, 250, image=tkimage)
self.master.after_idle(self.update)
yield
if i < number_cycles-1:
self.canvas.delete(self.canvas_obj)
angle += 10
angle %= 360
else:
yield
flag = False
# but_select image -------------------------------------
def but_select(self):
self.select_image()
def select_image(self):
pathToImage = filedialog.askopenfilename(
filetypes=[('PNG Files','*.png'),('JPG Files','*.jpg'),
('JPEG Files','*.jpeg')])
if not pathToImage: return
image = Image.open(str(pathToImage))
w, h = image.size
if w > 650:
k = w/650
_w = int(w/k)
_h = int(h/k)
image = image.resize((_w, _h), Image.ANTIALIAS)
w, h = image.size
if h > 450:
k = h/450
_w = int(w/k)
_h = int(h/k)
image = image.resize((_w, _h), Image.ANTIALIAS)
self.tkimage = image
image = self.make_square(im=image)
w, h = image.size
if w > 700:
k = w/700
_w = int(w/k)
_h = int(h/k)
image = image.resize((_w, _h), Image.ANTIALIAS)
w, h = image.size
if h > 500:
k = h/500
_w = int(w/k)
_h = int(h/k)
image = image.resize((_w, _h), Image.ANTIALIAS)
w, h = image.size
self.selectedImage = ImageTk.PhotoImage(image=image)
self.canvas.delete(self.canvas_obj)
self.canvas_obj = self.canvas.create_image(
(700-w)//2, (500-h)//2,
anchor=NW, image=self.selectedImage
)
self.label_pic_name['text'] = pathToImage
def make_square(self, im, min_size=256, fill_color = (112, 112, 112)):
x, y = im.size
size = max(min_size, x, y)
new_im = Image.new('RGBA', (size,size), (112, 112, 112, 255))
new_im.paste(im, (int((size - x) / 2), int((size - y) / 2)))
return new_im
def image_counter_clockwise(self):
self.update = self.draw2(number_cycles=11).__next__
self.master.after(100, self.update)
def image_clockwise(self):
self.update = self.draw2(number_cycles=11, delta_angle=-10).__next__
self.master.after(100, self.update)
def draw2(self, number_cycles=0, delta_angle=10):
image = self.tkimage
self.canvas.delete(self.canvas_obj)
angle = 0
i = 0
flag = True
while flag:
i += 1
if i < number_cycles:
tkimage = ImageTk.PhotoImage(image.rotate(angle))
self.canvas_obj = self.canvas.create_image(
350, 250, image=tkimage)
self.master.after_idle(self.update)
yield
if i < number_cycles-1:
self.canvas.delete(self.canvas_obj)
self.tkimage = image.rotate(angle)
angle += delta_angle
angle %= 360
else:
yield
flag = False
def enlarge_image(self):
w, h = self.tkimage.size
_w, _h = int(w * 1.1), int(h * 1.1)
if _w >= 700 or _h >= 500:
return
image = self.tkimage.resize((_w, _h), Image.ANTIALIAS)
self.selectedImage = ImageTk.PhotoImage(image=image)
self.canvas.delete(self.canvas_obj)
self.canvas_obj = self.canvas.create_image(
(700-_w)//2, (500-_h)//2,
anchor=NW, image=self.selectedImage
)
self.tkimage = image
def reduce_image(self):
w, h = self.tkimage.size
_w, _h = int(w // 1.1), int(h // 1.1)
if _w <= 140 or _h <= 100:
return
image = self.tkimage.resize((_w, _h), Image.ANTIALIAS)
self.selectedImage = ImageTk.PhotoImage(image=image)
self.canvas.delete(self.canvas_obj)
self.canvas_obj = self.canvas.create_image(
(700-_w)//2, (500-_h)//2,
anchor=NW, image=self.selectedImage
)
self.tkimage = image
root = Tk()
root['bg'] = 'grey44'
app = SimpleApp(root, 'lena2.png')
root.mainloop()
lena2.png

