i am making a paint like app in python using tkinter and turtle. im trying to save the image drawn as a png.
short version of my program :
import tkinter as tk
from functools import partial
from turtle import TurtleScreen, RawTurtle, Shape
from PIL import Image
def draw(x, y):
turtle.ondrag(None)
turtle.pendown()
turtle.goto(x, y)
turtle.penup()
screen.update()
turtle.ondrag(draw)
def move(x, y):
screen.onclick(None)
turtle.goto(x, y)
screen.onclick(move)
screen.update()
def set_color(color):
global pen_color
pen_color = color
turtle.pencolor(color)
screen.update()
# --- add widgets ---
root = tk.Tk()
canvas = tk.Canvas(root, width=500, height=500)
canvas.pack(side='right', expand=True, fill='both')
frame = tk.Frame(root)
frame.pack(side='left', fill='y')
tk.Label(frame, text='COLORS').grid(column=0, row=0)
tk.Button(frame, bg='red', width=10, command=partial(set_color, 'red')).grid(column=0, row=1)
tk.Button(frame, bg='yellow', width=10, command=partial(set_color, 'yellow')).grid(column=0, row=2)
tk.Button(frame, bg='green', width=10, command=partial(set_color, 'green')).grid(column=0, row=3)
tk.Button(frame, bg='blue', width=10, command=partial(set_color, 'blue')).grid(column=0, row=4)
tk.Button(frame, bg='black', width=10, command=partial(set_color, 'black')).grid(column=0, row=5)
def save () :
drawing = screen.getcanvas()
drawing.postscript(file='drawing.ps')
img = Image.open( 'drawing.ps')
img.save('drawing.png')
print('...dumping gui window to png')
bsave = tk.Button(
frame,
text='save *',
width=10,
command=save
)
bsave.grid(column=0, row=6)
screen = TurtleScreen(canvas)
screen.tracer(False)
pen_color = 'black'
turtle = RawTurtle(screen)
#turtle.hideturtle()
turtle.shape("circle")
polygon = turtle.get_shapepoly()
fixed_color_turtle = Shape("compound")
fixed_color_turtle.addcomponent(polygon, "", "")
screen.register_shape('fixed', fixed_color_turtle)
turtle.shape("fixed")
turtle.penup()
turtle.pensize(5)
turtle.turtlesize(2000,2000)
turtle.ondrag(draw)
screen.onscreenclick(move)
screen.update()
screen.mainloop()
when i run this i get the error : OSError : Unable to locate Ghostscript on paths
i want to save the image without using ghostscript as this program need to run on the school computers and they don't have it.
i also tried this but the x and y values returned are always wrong
def save () :
x0 = frame.winfo_rootx()
y0 = frame.winfo_rooty()
x1 = x0 + frame.winfo_width()
y1 = y0 + frame.winfo_height()
ImageGrab.grab().crop((x0, y0, x1, y1)).save('painting.png')
Your ImageGrab
approach was almost there. The only change I have made is to use root
instead of frame
. Sometimes it useful to adjust the result by the total border thickness which is composed of borderthickness and highlightthickness but in this case it seems that it is not necessary. Use it in another context if needed. The usual default values are assigned to the variables:
import tkinter as tk
from functools import partial
from turtle import TurtleScreen, RawTurtle, Shape
from PIL import Image
from PIL import ImageGrab
def draw(x, y):
turtle.ondrag(None)
turtle.pendown()
turtle.goto(x, y)
turtle.penup()
screen.update()
turtle.ondrag(draw)
def move(x, y):
screen.onclick(None)
turtle.goto(x, y)
screen.onclick(move)
screen.update()
def set_color(color):
global pen_color
pen_color = color
turtle.pencolor(color)
screen.update()
# --- add widgets ---
root = tk.Tk()
canvas = tk.Canvas(root, width=500, height=500)
canvas.pack(side='right', expand=True, fill='both')
frame = tk.Frame(root)
frame.pack(side='left', fill='y')
tk.Label(frame, text='COLORS').grid(column=0, row=0)
tk.Button(frame, bg='red', width=10, command=partial(set_color, 'red')).grid(column=0, row=1)
tk.Button(frame, bg='yellow', width=10, command=partial(set_color, 'yellow')).grid(column=0, row=2)
tk.Button(frame, bg='green', width=10, command=partial(set_color, 'green')).grid(column=0, row=3)
tk.Button(frame, bg='blue', width=10, command=partial(set_color, 'blue')).grid(column=0, row=4)
tk.Button(frame, bg='black', width=10, command=partial(set_color, 'black')).grid(column=0, row=5)
def save () :
bordterthickness = 2
highlightthickness = 1
brdt = bordterthickness + highlightthickness
x0 = frame.winfo_rootx()
y0 = frame.winfo_rooty()
x1 = x0 + root.winfo_width()
y1 = y0 + root.winfo_height()
ImageGrab.grab().crop((x0, y0, x1, y1)).save('saveScreenshot.png')
bsave = tk.Button(
frame,
text='save *',
width=10,
command=save
)
bsave.grid(column=0, row=6)
screen = TurtleScreen(canvas)
screen.tracer(False)
pen_color = 'black'
turtle = RawTurtle(screen)
#turtle.hideturtle()
turtle.shape("circle")
polygon = turtle.get_shapepoly()
fixed_color_turtle = Shape("compound")
fixed_color_turtle.addcomponent(polygon, "", "")
screen.register_shape('fixed', fixed_color_turtle)
turtle.shape("fixed")
turtle.penup()
turtle.pensize(5)
turtle.turtlesize(2000,2000)
turtle.ondrag(draw)
screen.onscreenclick(move)
screen.update()
screen.mainloop()
Below a screenshot of the Window:
Here the result of clicking the save
button: