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

Edited 5 Years Ago by Gribouillis: n/a

Attachments circles.jpg 126.85 KB

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

Edited 5 Years Ago by Gribouillis: n/a

Comments
You are maestro!
I like that soluion

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()
This question has already been answered. Start a new discussion instead.