InstaK0
InstaK0

Reputation: 362

How can I save a Turtle canvas as an image (.png or .jpg)

I've been working with the turtle module and want to use it as a starting point to work on a simple image recognition program that could recognize numbers/letters. I need to be able to save the turtle as an image I could manipulate - rescaling, rotating, etc. to try to regulate the images. I've been researching for hours and cannot seem to find anything that works. I have discovered how to save the Turtle output as a Tkinter canvas:

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

This seems to work great. The next step is to save that as a .png or .jpg. However, the only thing I can find is how to save it as a postscript file:

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

From there, I have attempted to convert the .ps file into a .png or .jpeg file using PIL. Here is my code for that and the error that I get:

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

Running the line "turtle_img.save("turtle_img", "png") produces:

OSError: Unable to locate Ghostscript on paths

I would love one of the following: 1. a way to convert a .ps into a .jpeg, .png, or even a bitmap 2. An alternate way of saving a Tkinter canvas that is easier to work with

EDIT: I wanted to clarify that I would be working with a large number of these and would like to automate the process in a script rather than use the command line for each image.

Upvotes: 3

Views: 8434

Answers (3)

Andreas
Andreas

Reputation: 146

ImageGrab.grab() doesn't seem to work quite well with turtle on my Mac, so here is an workaround to save a Turtle canvas as an image.

import turtle as t
from PIL import Image
import os

# ... do your turtle work here

canvas = t.getcanvas()
psFilename = "foo.ps"
canvas.postscript(file=psFilename)
psimage = Image.open(psFileName)
psimage.save("bar.png") # or any other image format that PIL supports.
os.remove(psFilename) # optional

It saves the canvas (the underlying Tkinter Canvas) as a postscript file, then uses PIL to convert it.

Upvotes: 1

KenS
KenS

Reputation: 31199

You can use Ghostscript to render a PostScript program to a bitmap. For example:

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

There are other file formats and colour depths available, such as png256, jpeg etc. If it's a multi-page input file then:

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

Upvotes: 2

Reblochon Masque
Reblochon Masque

Reputation: 36712

You can directly save the canvas as a .png if you include the turtle in a tkinter canvas. This is very easy to do.

Grabbing the .png image can then be automated, or be done at the click of a button, or the pressing of a key - without manual intervention.

Here is an example that embeds a turtle in a tk.Canvas, draws a Sierpinski Gasket, and automatically saves the image generated on disk.

enter image description here

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

Upvotes: 1

Related Questions