Python-Tkinter-绘制:如何平滑绘制并保存具有不同名称的图像?

时间:2018-09-03 09:09:16

标签: python-3.x tkinter python-imaging-library paint tkinter-canvas

我制作了一个绘画程序,但是每次绘制时都无法流畅地用不同的名称保存图像。请帮忙!

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()

I know, this is awful :(

2 个答案:

答案 0 :(得分:2)

如果要将图像另存为其他名称和扩展名,还可以使用另存为对话框:

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()

Paint.pyw - Drawing window

答案 1 :(得分: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()

据说并不比您的可怕,但是线条是连续的...

enter image description here