I was exploring random art and modified this nice example from vegaseat:

# random circles in Tkinter
# a left mouse double click will idle action for 5 seconds
# modified vegaseat's code from:
# http://www.daniweb.com/software-development/python/code/216626

import random as rn
import time
try:
    # Python2
    import Tkinter as tk
except ImportError:
    # Python3
    import tkinter as tk

def idle_5sec(event=None):
    """freeze the action for 5 seconds"""
    root.title("Idle for 5 seconds")
    time.sleep(5)
    root.title("Happy Circles ...")

# create the window form
root = tk.Tk()
# window title text
root.title("Happy Circles (click on window to idle for 5 seconds)")
# set width and height
w = 640
h = 480
# create the canvas for drawing
cv = tk.Canvas(width=w, height=h, bg='black')
cv.pack()
# endless loop to draw the random circles
while True:
    # random center (x,y) and radius r
    x = rn.randint(0, w)
    y = rn.randint(0, h)
    r = rn.randint(5, 50)
    # pick a random color
    # Tkinter color format is "#rrggbb"
    color = '#' + "".join("%02x"%rn.randrange(256) for x in range(3))
    # now draw the circle
    cv.create_oval(x, y, x+r, y+r, fill=color)
    # update the window
    root.update()
    # bind left mouse double click, idle for 5 seconds
    cv.bind('<Double-1>', idle_5sec)

# start the program's event loop
root.mainloop()

What I would like to do is to save the double clicked canvas to an image file like .jpg or .png format. Does anyone know how to do this?

Recommended Answers

You can also do it with PIL instead of ImageMagick
[code=python]
cv.postscript(file="circles.eps")
from PIL import Image
img = Image.open("circles.eps")
img.save("circles.png", "png")
[/code]

Jump to Post

Another way is to run Tkinter and PIL simultaneously. You can save the in memory PIL image in many file formats ...
[code]# random circles in Tkinter

a left mouse double click will idle action for 5 seconds and
save the canvas drawing to an image file
Jump to Post

All 4 Replies

I was exploring random art and modified this nice example from vegaseat:

# random circles in Tkinter
# a left mouse double click will idle action for 5 seconds
# modified vegaseat's code from:
# http://www.daniweb.com/software-development/python/code/216626

import random as rn
import time
try:
    # Python2
    import Tkinter as tk
except ImportError:
    # Python3
    import tkinter as tk

def idle_5sec(event=None):
    """freeze the action for 5 seconds"""
    root.title("Idle for 5 seconds")
    time.sleep(5)
    root.title("Happy Circles ...")

# create the window form
root = tk.Tk()
# window title text
root.title("Happy Circles (click on window to idle for 5 seconds)")
# set width and height
w = 640
h = 480
# create the canvas for drawing
cv = tk.Canvas(width=w, height=h, bg='black')
cv.pack()
# endless loop to draw the random circles
while True:
    # random center (x,y) and radius r
    x = rn.randint(0, w)
    y = rn.randint(0, h)
    r = rn.randint(5, 50)
    # pick a random color
    # Tkinter color format is "#rrggbb"
    color = '#' + "".join("%02x"%rn.randrange(256) for x in range(3))
    # now draw the circle
    cv.create_oval(x, y, x+r, y+r, fill=color)
    # update the window
    root.update()
    # bind left mouse double click, idle for 5 seconds
    cv.bind('<Double-1>', idle_5sec)

# start the program's event loop
root.mainloop()

What I would like to do is to save the double clicked canvas to an image file like .jpg or .png format. Does anyone know how to do this?

I was able to do it by saving the canvas as encapsulated postscript and then using ImageMagick to convert to jpg (this code was run in linux)

def idle_5sec(event=None):
    """freeze the action for 5 seconds and save image file"""
    root.title("Idle for 5 seconds")
    time.sleep(5)
    root.title("Happy Circles ...")
    cv.postscript(file="circles.eps") # save canvas as encapsulated postscript
    child = SP.Popen("mogrify -format jpg circles.eps", shell=True) # convert eps to jpg with ImageMagick
    child.wait()

You can also do it with PIL instead of ImageMagick

cv.postscript(file="circles.eps")
    from PIL import Image
    img = Image.open("circles.eps")
    img.save("circles.png", "png")
commented: You are maestro! +13
commented: I like that soluion +14

Another way is to run Tkinter and PIL simultaneously. You can save the in memory PIL image in many file formats ...

# random circles in Tkinter
# a left mouse double click will idle action for 5 seconds and
# save the canvas drawing to an image file
# the Tkinter canvas can only be saved in postscript format 
# run PIL imagedraw simultaneously which
# draws in memory, but can be saved in many formats
# modified vegaseat's code from (circles):
# http://www.daniweb.com/software-development/python/code/216626
# and (simultaneous PIL imagedraw):
# http://www.daniweb.com/software-development/python/code/216929

import random as rn
import time
from PIL import Image, ImageDraw
try:
    # Python2
    import Tkinter as tk
except ImportError:
    # Python3
    import tkinter as tk

def idle_5sec(event=None):
    """freeze the action for 5 seconds and save to file"""
    root.title("Idle for 5 seconds, save to file circles.png")
    time.sleep(5)
    root.title("Happy Circles ...")
    # PIL images can be saved as .png .jpg .gif or .bmp files
    filename = "happy_circles.jpg"
    # save the PIL image
    img_pil.save(filename)

# create the window form
root = tk.Tk()
# window title text
root.title("Happy Circles (click on window to idle for 5 seconds)")

# set width and height
w = 640
h = 480
# create the Tkinter canvas for drawing
cv_tk = tk.Canvas(width=w, height=h, bg='black')
cv_tk.pack()
# create a PIL canvas in memory and use in parallel
black = (0, 0, 0)
img_pil = Image.new("RGB", (w, h), black)
cv_pil = ImageDraw.Draw(img_pil)

# endless loop to draw the random circles
while True:
    # random center (x,y) and radius r
    x = rn.randint(0, w)
    y = rn.randint(0, h)
    r = rn.randint(5, 50)
    # create a random color for PIL and Tkinter
    # go from pil color (r, g, b) to tk color format "#rrggbb"
    color_pil = (rn.randrange(256), rn.randrange(256), rn.randrange(256))
    color_tk = '#' + "".join("%02x" % c for c in color_pil)
    # now draw the tk circle
    cv_tk.create_oval(x, y, x+r, y+r, fill=color_tk)
    # and the pil circle (memory only)
    cv_pil.ellipse((x, y, x+r, y+r), fill=color_pil, outline=black)
    # update the window
    root.update()
    # bind left mouse double click, idle for 5 seconds
    cv_tk.bind('<Double-1>', idle_5sec)

# start the program's event loop
root.mainloop()

You can also do it with PIL instead of ImageMagick

cv.postscript(file="circles.eps")
    from PIL import Image
    img = Image.open("circles.eps")
    img.save("circles.png", "png")

Could not get this work on my Windows XP machine, found this:
http://code.activestate.com/lists/python-tutor/71677/
which claims this to be "Unix only!"

commented: agree +14
commented: useful portability feedback +13