【问题标题】:How can I save a Turtle canvas as an image (.png or .jpg)如何将 Turtle 画布保存为图像(.png 或 .jpg)
【发布时间】:2020-09-14 19:30:24
【问题描述】:

我一直在使用海龟模块,并希望以此为起点来开发一个可以识别数字/字母的简单图像识别程序。我需要能够将海龟保存为我可以操纵的图像 - 重新缩放、旋转等以尝试调节图像。我已经研究了几个小时,似乎找不到任何有效的方法。我发现了如何将 Turtle 输出保存为 Tkinter 画布:

import turtle
t = turtle.Turtle()
# Draw something
canvas = t.getscreen().getcanvas()  # Saves a Tkinter canvas object

这似乎工作得很好。下一步是将其保存为 .png 或 .jpg。但是,我唯一能找到的是如何将其保存为 postscript 文件:

canvas.postscript(file="turtle_img.ps")  # Saves as a .ps file

从那里,我尝试使用 PIL 将 .ps 文件转换为 .png 或 .jpeg 文件。这是我的代码和我得到的错误:

from PIL import Image
turtle_img = Image.open("turtle_img.ps")
turtle_img.save("turtle_img", "png")
# Also tried:   turtle_img.save("turtle_img, "jpeg")

运行 "turtle_img.save("turtle_img", "png") 会产生:

OSError: Unable to locate Ghostscript on paths

我会喜欢以下其中一项: 1. 一种将 .ps 转换为 .jpeg、.png 甚至位图的方法 2.另一种保存 Tkinter 画布的方法,更易于使用

编辑:我想澄清一下,我将使用大量这些,并希望在脚本中自动化该过程,而不是为每个图像使用命令行。

【问题讨论】:

    标签: python-3.x tkinter turtle-graphics tkinter-canvas python-turtle


    【解决方案1】:

    您可以使用 Ghostscript 将 PostScript 程序渲染为位图。例如:

    gs -sDEVICE=png16m -o out.png input.ps
    

    还有其他可用的文件格式和颜色深度,例如 png256、jpeg 等。如果是多页输入文件,则:

    gs -sDEVICE=png16m -o out%d.png input.ps
    

    【讨论】:

    • 非常感谢您的快速响应。我应该澄清一下,有没有办法用 Ghostscript 自动化它?我宁愿把它写到一个脚本而不是从命令行运行它。
    • 嗯,不知道你所说的“自动化”是什么意思。如果有帮助,您可以将命令行放在脚本中。 FWIW -o 指定输出文件名,还包括 NOPAUSE(因此它不会暂停页面之间的输入)和 BATCH,因此它在完成时退出。
    • 我的意思是写一个我可以随时运行的脚本,而不是直接与命令行交互。我使用 PyCharm 编写程序,不确定“脚本”是否正确。
    • 是的,很抱歉,但我仍然不明白你想要什么,几乎可以肯定,因为我对 Python 一无所知。我相信 Ghostscript 的某个地方有 Python 绑定,如果这是你想要的,但我对它们一无所知。哦,看起来它叫 PyPl。
    • 感谢您昨天对这篇文章和其他人的所有帮助。找到解决方案,现在使用 PIL 可以完美运行。谢谢!
    【解决方案2】:

    如果将turtle 包含在tkinter canvas 中,则可以将画布直接保存为.png。这很容易做到。

    然后可以自动抓取.png 图像,或者通过点击按钮或按键来完成 - 无需人工干预

    这是一个在tk.Canvas 中嵌入turtle、绘制谢尔宾斯基垫片并自动将生成的图像保存在磁盘上的示例。

    import tkinter as tk
    from PIL import ImageGrab
    import turtle
    
    
    def dump_gui():
        """
        takes a png screenshot of a tkinter window, and saves it on in cwd
        """
        print('...dumping gui window to png')
    
        x0 = root.winfo_rootx()
        y0 = root.winfo_rooty()
        x1 = x0 + root.winfo_width()
        y1 = y0 + root.winfo_height()
        ImageGrab.grab().crop((x0, y0, x1, y1)).save("gui_image_grabbed.png")
    
    
    def draw_sierpinski(length, depth):
        if depth == 0:
            for i in range(0, 3):
                t.fd(length)
                t.left(120)
        else:
            draw_sierpinski(length / 2, depth - 1)
            t.fd(length / 2)
            draw_sierpinski(length / 2, depth - 1)
            t.bk(length / 2)
            t.left(60)
            t.fd(length / 2)
            t.right(60)
            draw_sierpinski(length / 2, depth - 1)
            t.left(60)
            t.bk(length / 2)
            t.right(60)
    
    
    root = tk.Tk()
    canvas = tk.Canvas(root, width=500, height=500)
    canvas.pack()
    
    t = turtle.RawTurtle(canvas)
    
    t.penup()
    t.goto(-200, -175)
    t.pendown()
    draw_sierpinski(400, 6)
    t.hideturtle()
    
    dump_gui()
    
    root.mainloop()
    

    【讨论】:

    • 感谢您的回答!我已经解决了这个问题,但如果我重新编写代码,我可能会尝试合并这个解决方案。
    最近更新 更多