WinEunuuchs2Unix
WinEunuuchs2Unix

Reputation: 1939

Python Tkinter PIL generate random 200x200 image

In Python Tkinter this code:

# custom indicator images
im_open = Image.new('RGBA', (15, 15), '#00000000')
im_empty = Image.new('RGBA', (15, 15), '#00000000')
draw = ImageDraw.Draw(im_open)
draw.polygon([(0, 4), (14, 4), (7, 11)], fill='yellow', outline='black')
im_close= im_open.rotate(90)

Generates a triangle in a format I can use:

screenshot


In Python tkinter this code draws on a canvas I can't use:

COLORS = ['snow', 'ghost white', 'white smoke', 'gainsboro', 'floral white', 'old lace' ...]

for x in range(0, 40):

    x1 = random.randint(0,400)
    y1 = random.randint(0,400)
    x2 = random.randint(0,400)
    y2 = random.randint(0,400)
    x3 = random.randint(0,400)
    y3 = random.randint(0,400)

    my_triangle = canvas.create_polygon(x1, y1, x2, y2, x3, y3,\
                  fill = (random.sample(COLORS, 1)[0]), 
                  outline = random.sample(COLORS, 1)[0])

However it creates desirable images:

Tk Window Output 1


The first code set generates an image in memory like I need but uses a triangle which I don't want. The second code set generates a canvas memory map which I don't want but has random shapes which I do want.

To improve the random polygon shapes in the second code set, circles and rectangles can be thrown in. Also the second code set contains color names but random R:G:B channels would be preferable.

To select random shapes and colors the current YY:MM:DD or HH:MM:SS could be used. This is to generate random Album Artwork for home made music player when nothing is encoded to song or as a placeholder before real artwork is obtained.

In case it matters, platform is Ubuntu 16.04.6 LTS, kernel 4.14.188, Python 2.7.12 plus Tkinter, PIL and Tkinter-Image (stuff).

Upvotes: 0

Views: 1388

Answers (1)

user14005715
user14005715

Reputation:

Generate PIL.Image objects, with randomly generated:
shapes, fill & outline colors.

The resulting images are drawn to a tk.Canvas, for display;
that is irrelevant / for presentation purposes.
(The images themselves are in the requested format.)

from datetime import datetime
from PIL import Image, ImageDraw, ImageTk
from random import randint, randrange

# Create random indicator images.

WIDTH, HEIGHT = 50, 50
COUNT = 100

# Use datetime (somehow), to generate random int.
def datetimeToInt(): 
  y, m, d, hour, min, sec = datetime.now().timetuple()[0:6]
  return y + m + d + hour + min + sec

def randRgb(): 
  return(randint(0, 255), randint(0, 255), randint(0, 255))

def randTriangle():
  x1, y1 = randrange(0, WIDTH), randrange(0, HEIGHT)
  x2, y2 = randrange(0, WIDTH), randrange(0, HEIGHT)
  x3, y3 = randrange(0, WIDTH), randrange(0, HEIGHT)
  return [(x1,y1), (x2,y2), (x3,y3)]

def randRect():
  x1, y1 = randrange(0, WIDTH), randrange(0, HEIGHT)
  x2, y2 = randrange(0, WIDTH), randrange(0, HEIGHT)
  return [(x1,y1), (x2,y2)]
  return

randEllipse = randRect

# Map: random shape creation functions -> ImageDraw methods
shapeFactories = [
  (randTriangle, ImageDraw.ImageDraw.polygon),
  (randRect, ImageDraw.ImageDraw.rectangle),
  (randEllipse, ImageDraw.ImageDraw.ellipse)
]
shapeFactoriesCount = len(shapeFactories)

imgOpenList = []
imgClosedList = []
for x in range(COUNT):
  # Get random index, within full range:
  #randIdx = randrange(0, shapeFactoriesCount)
  # Use random int, generated from datetime (somehow):
  randIdx = datetimeToInt() % shapeFactoriesCount
  shapeFactory, drawMethod = shapeFactories[randIdx]
  
  im_open = Image.new('RGBA', (WIDTH, HEIGHT), '#00000000')
  draw = ImageDraw.Draw(im_open)
  drawMethod(  # passing 'self'/'draw' explicitly to method:
    draw, shapeFactory(), fill=randRgb(), outline=randRgb()
  )
  
  imgOpenList.append(im_open)
  imgClosedList.append(im_open.rotate(90))

# The rest is just for displaying the resulting images.

import tkinter as tk

from math import floor, sqrt

root = tk.Tk()

imgOpenList = [
  ImageTk.PhotoImage(img) for img in imgOpenList
]
imgClosedList = [
  ImageTk.PhotoImage(img) for img in imgClosedList
]

imgsPerAxis = floor(sqrt(COUNT))  # rough approximation
canvas = tk.Canvas(
  root,
  width=WIDTH * imgsPerAxis * 2,  # x2: open & closed images
  height=HEIGHT * imgsPerAxis
)
canvas.pack()

for i in range(imgsPerAxis):
  for j in range(imgsPerAxis):
    canvas.create_image(
      2*j*WIDTH, i*HEIGHT, 
      image=imgOpenList[i*imgsPerAxis + j],
      anchor=tk.NW
    )
    canvas.create_image(
      (2*j+1)*WIDTH, i*HEIGHT,
      image=imgClosedList[i*imgsPerAxis + j],
      anchor=tk.NW
    )

root.mainloop()

Could you post the code that uses these images, as icons*?
(* in what looks like a tree-view, in your GUI)
(I'm curious, don't remember seeing custom icons there.)

enter image description here


If instead of individual icons, you want a composite image:

from datetime import datetime
from PIL import Image, ImageDraw, ImageTk
from random import randint, randrange

# Create random composite image.

WIDTH, HEIGHT = 200, 200
COUNT = 40

# Use datetime (somehow), to generate random int.
def datetimeToInt(): 
  y, m, d, hour, min, sec = datetime.now().timetuple()[0:6]
  return y + m + d + hour + min + sec

def randRgb(): 
  return(randint(0, 255), randint(0, 255), randint(0, 255))

def randTriangle():
  x1, y1 = randrange(0, WIDTH), randrange(0, HEIGHT)
  x2, y2 = randrange(0, WIDTH), randrange(0, HEIGHT)
  x3, y3 = randrange(0, WIDTH), randrange(0, HEIGHT)
  return [(x1,y1), (x2,y2), (x3,y3)]

def randRect():
  x1, y1 = randrange(0, WIDTH), randrange(0, HEIGHT)
  x2, y2 = randrange(0, WIDTH), randrange(0, HEIGHT)
  return [(x1,y1), (x2,y2)]
  return

randEllipse = randRect

# Map: random shape creation functions -> ImageDraw methods
shapeFactories = [
  (randTriangle, ImageDraw.ImageDraw.polygon),
  (randRect, ImageDraw.ImageDraw.rectangle),
  (randEllipse, ImageDraw.ImageDraw.ellipse)
]
shapeFactoriesCount = len(shapeFactories)

composite = Image.new('RGBA', (WIDTH, HEIGHT), '#00000000')
draw = ImageDraw.Draw(composite)
for x in range(COUNT):
  # Get random index, within full range:
  #randIdx = randrange(0, shapeFactoriesCount)
  # Use random int, generated from datetime (somehow):
  randIdx = datetimeToInt() % shapeFactoriesCount
  shapeFactory, drawMethod = shapeFactories[randIdx]
  
  drawMethod(  # passing 'self'/'draw' explicitly to method:
    draw, shapeFactory(), fill=randRgb(), outline=randRgb()
  )

# The rest is just for displaying the resulting images.
import tkinter as tk
root = tk.Tk()
compositeTk = ImageTk.PhotoImage(composite)
tk.Label(image=compositeTk).pack()
root.mainloop()

enter image description here

Upvotes: 1

Related Questions