Python - Tkinter - Paint: Как рисовать плавно и сохранять изображения под разными именами?
Я сделал программу рисования, но я не могу рисовать плавно и сохранять изображения каждый раз под разными именами. Пожалуйста помоги!
from tkinter import *
# by Canvas I can't save image, so i use PIL
import PIL
from PIL import Image, ImageDraw
def save():
filename = 'image.png'
image1.save(filename)
def paint(event):
x1, y1 = (event.x), (event.y)
x2, y2 = (event.x + 1), (event.y + 1)
cv.create_oval((x1, y1, x2, y2), fill='black', width=10)
# --- PIL
draw.line((x1, y1, x2, y2), fill='black', width=10)
root = Tk()
cv = Canvas(root, width=640, height=480, bg='white')
# --- PIL
image1 = PIL.Image.new('RGB', (640, 480), 'white')
draw = ImageDraw.Draw(image1)
# ----
cv.bind('<B1-Motion>', paint)
cv.pack(expand=YES, fill=BOTH)
btn_save = Button(text="save", command=save)
btn_save.pack()
root.mainloop()
1 ответ
Вы можете использовать непрерывное рисование вместо того, чтобы рисовать отдельные маленькие круги.
В следующем примере хранятся последние значения положения мыши, чтобы нарисовать линию к текущему значению.
Вы должны нажать и переместить мышь, чтобы нарисовать; отпустите кнопку, чтобы остановить.
Имя изображения содержит число, которое увеличивается на 1 при каждом сохранении; поэтому вы можете сохранить все промежуточные изображения, когда рисуете полную картину.
from tkinter import *
import PIL
from PIL import Image, ImageDraw
def save():
global image_number
filename = f'image_{image_number}.png' # image_number increments by 1 at every save
image1.save(filename)
image_number += 1
def activate_paint(e):
global lastx, lasty
cv.bind('<B1-Motion>', paint)
lastx, lasty = e.x, e.y
def paint(e):
global lastx, lasty
x, y = e.x, e.y
cv.create_line((lastx, lasty, x, y), width=1)
# --- PIL
draw.line((lastx, lasty, x, y), fill='black', width=1)
lastx, lasty = x, y
root = Tk()
lastx, lasty = None, None
image_number = 0
cv = Canvas(root, width=640, height=480, bg='white')
# --- PIL
image1 = PIL.Image.new('RGB', (640, 480), 'white')
draw = ImageDraw.Draw(image1)
cv.bind('<1>', activate_paint)
cv.pack(expand=YES, fill=BOTH)
btn_save = Button(text="save", command=save)
btn_save.pack()
root.mainloop()
Якобы не менее страшный, чем ваш, но линии сплошные...
Вы также можете использовать диалог Сохранить как, если хотите сохранить изображение с другим именем и расширением:
from tkinter import *
from tkinter.filedialog import asksaveasfilename as saveAs
import PIL
from PIL import Image, ImageDraw
def save():
filename=saveAs(title="Save image as...",filetype=(("PNG images","*.png"),("JPEG images","*.jpg"),("GIF images","*.gif")))
image1.save(filename)
def activate_paint(e):
global lastx, lasty
cv.bind('<B1-Motion>', paint)
lastx, lasty = e.x, e.y
def paint(e):
global lastx, lasty
x, y = e.x, e.y
cv.create_line((lastx, lasty, x, y), width=1)
draw.line((lastx, lasty, x, y), fill='black', width=1)
lastx, lasty = x, y
def clear():
cv.delete('all')
def exitt():
exit()
win = Tk()
win.title("Paint - made in Python")
win.iconbitmap('Paint.ico') # Delete this line if you don't have file "Paint.ico" in this folder
lastx, lasty = None, None
cv = Canvas(win, width=640, height=480, bg='white')
image1 = PIL.Image.new('RGB', (640, 480), 'white')
draw = ImageDraw.Draw(image1)
cv.bind('<1>', activate_paint)
cv.pack(expand=YES, fill=BOTH)
save_ = Button(text="Save image", command=save)
save_.pack()
reset=Button(text='Reset canvas',command=clear)
reset.pack(side=LEFT)
_exit=Button(text='Exit',command=exitt)
_exit.pack(side=RIGHT)
win.mainloop()