Automatic Art

A couple of years ago I had a go at seeing if I could write an app that made art automatically. The original app was written in Java and made available on the App Store for Android. It makes a new image every five seconds. I recently rewrote this for Python 3.

Blue Moon
Sad day

I need to sort out my git repository so until then I will post the code below.

Checkers 2

I’d be interested to know what you think.

Rising Sun
Diving
City Sunset
import pygame
import os
import random
import datetime
from PIL import Image

""" Initiate pygame"""
pygame.init()

""" set up variables """
info = pygame.display.Info()
clock = pygame.time.Clock()
WIDTH = info.current_w
HEIGHT = info.current_h

# temp
WIDTH = 600
HEIGHT = WIDTH
BRUSH = 30
MOVE = 100000
pm = 4

# art variables
maxObjects = 100
exportImage = False
complexity = "simple" # "simple, basic" or "complex"
shapes = ["ellipse", "rect", "polygon"]
multiplier = 3
painting = []
saveFolder = PATH_TO_YOUR_SAVE_FOLDER

# Frames per second
FPS = 5

# display screen
display = True

# log to screen
log = True

# Initiate mainloop
mainloop = True

def main():
    """ main loop """
    mainloop = True
    count = 10

    """set up display"""
    if display:
        # screen = pygame.display.set_mode(
        #     (WIDTH, HEIGHT), pygame.FULLSCREEN)  # set screen size
        screen = pygame.display.set_mode(
            (WIDTH, HEIGHT))  # set screen size
        # Show/Hide mouse - show = 1 hide = 0
        pygame.mouse.set_visible(1)
        # create an empty pygame surface
        background = pygame.Surface(screen.get_size())
        background.fill((255, 255, 255))  # fill the background with white
        foreground = pygame.Surface(screen.get_size())
        # background.fill((0, 255, 0))  # fill the background with green
        background = background.convert()  # convert surface to make blitting faster

    else:
        pass

    """ get Art """
    foreground = makeArt(foreground)
############################################################################
    """ Main loop """
    while mainloop:

        if log:
            print(count)
        else:
            pass

        if display:
            """ draw """
            screen.blit(background, (0, 0))  # copy background to screen
            screen.blit(foreground, (0, 0))  # copy background to screen

            """ update display """
            pygame.display.flip()
        else:
            pass

        if count <= 0:
            """exit mainloop"""
            foreground.fill((255, 255, 255))
            foreground = makeArt(foreground)
            count = 10
        else:
            count -= 1

        if count == 9 and exportImage:
            date_time = datetime.datetime.now()
            filename = "Type2_"
            filename+= date_time.strftime("%Y")
            filename+= date_time.strftime("%b")
            filename+= date_time.strftime("%d")
            filename+= "_"
            filename+= date_time.strftime("%H")
            filename+= date_time.strftime("%M")
            filename+= date_time.strftime("%S")

            filename+=".jpg"

            date = date_time.strftime("%Y")
            date += date_time.strftime("%b")
            date += date_time.strftime("%d")

            print(filename)

            directory = os.path.join(saveFolder, date)

            if not os.path.exists(directory):
                os.makedirs(directory)

            saveFolderPath = os.path.join(directory, filename)

            pygame.image.save(foreground, saveFolderPath)

        # FPS
        clock.tick(FPS)

        """Process events"""
        mainloop = getEventHandler()

        # END MAIN LOOP

    """Exit PyGame"""
    pygame.quit()

    return

def makeArt(foreground):
    objects = getNoOfObjects()

    #print(f"objects: {objects}")

    for i in range(objects):
        #create a random colour

        r = random.randrange(0, 255)
        g = random.randrange(0, 255)
        b = random.randrange(0, 255)

        colour = (r,g,b)

        #print(f"Colour: r={r} g={g} b={b}")

        shape = getShape()
        # print(shape)

        x = getRandomX()
        y = getRandomY()

        wi = BRUSH#getRandomX()
        ht = BRUSH#getRandomY()

        movement = random.randrange(MOVE)

        # Can't remember what his is doing or why it is needed??

        if (i < objects/2):
            x = (getRandomX() * multiplier) - WIDTH
            y = (getRandomY() * multiplier) - HEIGHT

            wi = BRUSH#getRandomX() * multiplier
            ht = BRUSH#getRandomY() * multiplier

        #print(f"x {x} y {y} wi {wi} ht {ht}")

        rotX = getRandomX()
        rotY = getRandomY()

        scaleX = getScale()
        scaleY = getScale()

        angle = getAngle()

        #print(f"rotX {rotX} rotY {rotY} scaleX {scaleX} scaleY {scaleY} angle {angle}")

        if shape == "rect":
            pygame.draw.rect(foreground, colour, (x,y,wi,ht), 0)
        elif shape == "ellipse":
            for i in range(movement):
                pygame.draw.ellipse(foreground, colour, (x,y,wi,ht), 0)
                x_plusMinus = random.randrange(-pm*4, pm*4)
                #print(x_plusMinus)
                y_plusMinus = random.randrange(-pm*4, pm*4)
                #print(y_plusMinus)
                #print()
                x+=x_plusMinus
                y+=y_plusMinus
        else:
            shape == "polygon"
            noOfSides = random.randrange(3,10)
            pointlist = []
            for j in range(noOfSides):
                xx = (getRandomX() * multiplier) - WIDTH
                yy = (getRandomY() * multiplier) - HEIGHT

                pointlist.append((xx,yy))
            pygame.draw.polygon(foreground, colour, pointlist, 0)
    return foreground

def getAngle():
    a = random.randrange(360)
    return a

def getScale():
    s = random.randrange(100)/100.0
    return s

def getRandomX():
    rand_x = random.randrange(WIDTH)
    return rand_x

def getRandomY(): 
    rand_y = random.randrange(HEIGHT)
    return rand_y

def getShape():
    arrayLen = 1;
    if complexity == "simple":
        arrayLen = 1
    elif complexity == "basic":
        arrayLen = 2
    else:
        arrayLen = 3

    i = random.randrange(arrayLen)

    shape = shapes[i]
    return shape

def getNoOfObjects():
    noObjects = random.randrange(1,maxObjects)
    return noObjects;

def getEventHandler():

    mainloop = True

    """ event handler """
    for event in pygame.event.get():
        if event.type == pygame.QUIT:  # User presses QUIT
            mainloop = False  # pygame window closed by user

        if event.type == pygame.KEYDOWN:  # User presses ESCAPE
            if (event.key == pygame.K_ESCAPE):  # User presses ESCAPE
                mainloop = False

    return mainloop

""" bootstrap """
if __name__ == '__main__':
    """launch main first """
    main()

Leave a Reply