【发布时间】:2023-02-06 10:41:24
【问题描述】:
我正在创建一个绘画应用程序,我想在我的计算机上将画布小部件上的绘图保存为 png 文件。这是我的代码:
from tkinter import *
from tkinter.filedialog import *
from functools import partial
from tkinter import Menu
from tkinter import filedialog,messagebox
from PIL import Image
from tkinter.colorchooser import askcolor
import pyscreenshot as ImageGrab
import pyautogui
class PaintingApp:
x=y=None
def __init__(self,window):
self.window = window
self.upper_frame = Frame(window)
self.upper_frame.grid(row=0,column=0, padx=10, pady=5,sticky="ew")
self.lower_frame = Frame(window)
self.lower_frame.grid(row=2, column=0, padx=10, pady=5,sticky="ew")
self.canvas= Canvas(self.lower_frame,width=500,height=530,bg="white")
self.canvas.grid()
self.objects = [] #objects on canvas
self.pen_size = 2
self.pcolor = "black"
self.pen = Button(self.upper_frame,text="Pen",command=partial(self.pen_draw,thickness=self.pen_size))
self.pen.grid(row=0,column=3,padx=(10,160))
self.bg = Button(self.upper_frame,text="Background",command= self.bgcolor) #change bg color
self.bg.grid(row=2,column=1,padx=(100,10))
self.upper_menu()
self.canvas.bind("<Button-1>", self.get_x_and_y)
self.canvas.bind("<B1-Motion>", lambda event, b=self.pen_size: self.pen_draw(b,event))
self.im = None
def save_pic(self,event=None):
file = asksaveasfilename(defaultextension=".png")
x = self.canvas.winfo_rootx() + self.canvas.winfo_x()
y = self.canvas.winfo_rooty() + self.canvas.winfo_y()
x1 = x + self.canvas.winfo_width()
y1 = y + self.canvas.winfo_height()
self.im=ImageGrab.grab(bbox=(x,y,x1,y1))
self.im.save(file[19:])
def pen_color(self,color):
self.pcolor= color
def get_x_and_y(self,event):
global x,y
x, y = event.x, event.y
def pen_draw(self,thickness,event=None):
global x,y
self.canvas.bind("<Button-1>", self.get_x_and_y) # Bind to pen_draw function
self.canvas.bind("<B1-Motion>", lambda event, b=self.pen_size: self.pen_draw(b,event))
if event != None:
self.objects.append(self.canvas.create_line((x, y, event.x, event.y), fill=self.pcolor,width=self.pen_size,capstyle=ROUND,smooth=True))
x, y = event.x, event.y
def upper_menu(self):
self.menubar = Menu(window)
self.menu1 = Menu(self.menubar, tearoff=0)
self.menu1.add_command(label="Save pic", command=self.save_pic)
self.menu1.add_separator()
self.menu1.add_command(label="Exit", command=window.destroy)
self.menubar.add_cascade(label="Settings", menu=self.menu1)
self.menu2 = Menu(self.menubar, tearoff=0)
self.menu2.add_command(label="Open pic")
self.menubar.add_cascade(label="Image", menu=self.menu2)
self.window.config(menu=self.menubar)
def bgcolor(self):
chosen_color = askcolor(color=self.canvas["bg"])[1]
self.canvas.configure(bg=chosen_color)
window = Tk()
window.geometry("500x450")
p = PaintingApp(window)
window.mainloop()
现在我已经尝试了很多代码,但它不起作用。我上面提供的代码保存了一张没有任何意义的全黑图片。我也尝试过使用模块 pyautogui,但我仍然得到相同的结果。
def save_pic(self,event=None):
file = asksaveasfilename(defaultextension=".png")
x = self.canvas.winfo_rootx() + self.canvas.winfo_x()
y = self.canvas.winfo_rooty() + self.canvas.winfo_y()
x1 = x + self.canvas.winfo_width()
y1 = y + self.canvas.winfo_height()
self.im=pyautogui.screenshot(region=(x,y,x1,y1))
self.im.save(file[19:])
【问题讨论】:
-
您是否尝试检查
(x, y, x1, y1)是否是您想要的区域? -
@acw1668 我认为这是正确的区域。无论哪种方式,我唯一得到的是一张黑色图片。
-
无法重现黑色图像问题。实际上使用
.winfo_rootx()和.winfo_rooty()就足够了,不需要添加.winfo_x()和.winfo_y()(.winfo_x()和.winfo_y()为您的案例返回0)。你可以通过在self.canvas.grid(...)中添加padx=...和pady=...来测试它,你会得到一个错误区域的图像。并且窗口大小不足以显示所有画布,因此窗口外的区域也会被捕获。另外我不明白为什么使用file[19:]而不是file。
标签: python tkinter tkinter-canvas