Как сохранить рисунок черепахи в формате png?

Я создаю приложение, похожее на краску, на Python, используя tkinter и черепаху. Я пытаюсь сохранить изображение, нарисованное в формате PNG.

короткая версия моей программы:

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

когда я запускаю это, я получаю сообщение об ошибке: OSError: невозможно найти Ghostscript на путях

Я хочу сохранить изображение без использования Ghostscript, поскольку эту программу необходимо запускать на школьных компьютерах, а у них ее нет.

я тоже пробовал это, но возвращаемые значения x и y всегда неверны

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')
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
86
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете использовать что-то вроде этого:

from tkinter import *
import turtle

turtle.forward(100)
screen = turtle.getscreen()

screen.getcanvas().postscript(file = "FILE_NAME.eps")

Это сохраняет его как файл eps, вы можете просмотреть его в Интернете или погуглить, как конвертировать в png.

Спасибо! но сохранение в формате .eps мне не помогает

Percy 30.04.2024 19:28

За документацией действительно сложно следить, но в документации черепахи говорится, что screen.getcanvas() возвращает холст Tk (TkInter), поэтому я думаю, что ваш вопрос заключается в том, как сохранить PNG из Tk Canvas . Насколько я могу судить, виджет Tk canvas может сохранять только в PostScript (/EPS/PDF), что, очевидно, он и делает с помощью Ghostscript. У вас могут быть другие варианты, если у вас есть пакет Tk Img, но мне это не понятно.

То, что я считал ответом, похоже, не работает (дайте мне знать, если да) - Как преобразовать содержимое холста в изображение . Однако: пробовали ли вы просто использовать drawing.postscript(file='drawing.png')? Документ TkInter.Images предполагает, что он будет записывать растровые изображения, поскольку он подключается к любому параметру file или data.

Для моего собственного любопытства, не работает ли прямое сохранение в формате «drawing.png»? Похоже, что это должна быть ошибка, если судить по документации.

rand'Chris 02.05.2024 21:57
Ответ принят как подходящий

Ваш ImageGrab подход был почти готов. Единственное изменение, которое я сделал, — это использовать root вместо frame. Иногда бывает полезно скорректировать результат по общей толщине границы, которая состоит из borderthickness и highlightthickness, но в данном случае кажется, что в этом нет необходимости. При необходимости используйте его в другом контексте. Переменным присваиваются обычные значения по умолчанию:

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

Ниже скриншот окна:

Вот результат нажатия кнопки save:

Другие вопросы по теме