2019-09-12 19:53:57 +02:00
|
|
|
#!/usr/bin/env python3
|
2019-09-09 17:32:07 +02:00
|
|
|
from PIL import Image
|
|
|
|
from PIL import ImageFont
|
|
|
|
from PIL import ImageDraw
|
|
|
|
import csv
|
|
|
|
import random
|
2019-09-24 13:26:31 +02:00
|
|
|
import os
|
2020-12-17 01:31:57 +01:00
|
|
|
import json
|
2019-09-24 13:26:31 +02:00
|
|
|
|
|
|
|
fileDir = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
|
2019-09-09 17:32:07 +02:00
|
|
|
|
2020-12-17 01:31:57 +01:00
|
|
|
def replaceText(text,config):
|
2019-09-24 13:26:31 +02:00
|
|
|
"""This function replace $WILDCARD with a word found in subs.csv
|
|
|
|
subs.csv definition is 1st colum $WILDCARD, subsequent columns, possible values (chosen at random), delimiter is ;"""
|
2020-12-17 20:09:34 +01:00
|
|
|
with open(config["csvLocation"]+"/"+config["csvSubs"]) as subs:
|
2020-12-02 02:14:20 +01:00
|
|
|
csvReader = csv.reader(subs,delimiter=";")
|
2019-09-17 17:52:21 +02:00
|
|
|
for row in csvReader:
|
|
|
|
if text.find(row[0]) != -1:
|
2019-10-28 23:56:31 +01:00
|
|
|
text = text.replace(row[0],row[random.randint(1,len(row)-1)],1)
|
2019-09-17 17:52:21 +02:00
|
|
|
return text
|
|
|
|
|
2020-12-17 01:31:57 +01:00
|
|
|
def fetchText(indText,config):
|
2019-09-24 13:26:31 +02:00
|
|
|
"""This function fetch the text for the image with two characters
|
2020-12-02 02:14:20 +01:00
|
|
|
rtext.csv definition is: 1st column the name of the file (i.e. B001.png), 2nd number of actors (at the moment
|
|
|
|
they are limited to two; then a couple of columns or each actor with x and y coord of the strings; after the coords the outcomes,
|
|
|
|
one column for each actor
|
2019-09-24 13:26:31 +02:00
|
|
|
Delimiter is ; and line feeds @, if there aren't any options, it returns 0 (no text)
|
2020-12-02 02:14:20 +01:00
|
|
|
It returns two arrays, coords is a tuple (x,y) and result is the outcome"""
|
2020-12-17 20:09:34 +01:00
|
|
|
with open(config["csvLocation"]+"/"+config["csvSpeech"]) as rtext:
|
2019-09-24 13:26:31 +02:00
|
|
|
csvReader = csv.reader(rtext,delimiter=';')
|
|
|
|
for row in csvReader:
|
|
|
|
if row[0]==indText:
|
2020-12-02 02:14:20 +01:00
|
|
|
noActors = int(row[1])
|
|
|
|
if noActors == 0:
|
2019-09-24 13:26:31 +02:00
|
|
|
return 0
|
2020-12-02 02:14:20 +01:00
|
|
|
else:
|
|
|
|
firstElement = 2+(noActors*2)
|
|
|
|
lastElement = len(row)-(noActors-1)
|
|
|
|
randQuote = random.randrange(firstElement,lastElement,noActors)
|
|
|
|
coords = []
|
|
|
|
result = []
|
|
|
|
for x in range(0,noActors):
|
|
|
|
coords.append((row[2+x*2],row[3+x*2]))
|
|
|
|
result.append(row[randQuote+x])
|
|
|
|
return coords,result
|
|
|
|
|
2019-09-24 13:26:31 +02:00
|
|
|
|
2020-12-17 01:31:57 +01:00
|
|
|
def fetchVign(config):
|
2019-09-24 13:26:31 +02:00
|
|
|
"""This functions fetch an image, randomly, chosen from a markov tree defined in ram.csv
|
|
|
|
ram.csv definition is: 1st column the name of the image (without extension), subsequent columns, possible outcomes chosen randomly
|
|
|
|
It returns an array with the file names"""
|
2019-09-09 17:32:07 +02:00
|
|
|
starts = []
|
|
|
|
startdest = []
|
|
|
|
nvign = 0
|
|
|
|
currVign = "000"
|
|
|
|
story = []
|
2020-12-17 20:09:34 +01:00
|
|
|
with open(config["csvLocation"]+"/"+config["csvTree"]) as ram:
|
2019-09-09 17:32:07 +02:00
|
|
|
csvReader = csv.reader(ram)
|
|
|
|
for row in csvReader:
|
|
|
|
starts.append(row[0])
|
|
|
|
startdest.append(row)
|
2020-06-29 23:48:05 +02:00
|
|
|
while nvign <100:
|
2019-09-09 17:32:07 +02:00
|
|
|
story.append(startdest[starts.index(currVign)][random.randint(1,len(startdest[starts.index(currVign)])-1)])
|
|
|
|
currVign = story[nvign]
|
2020-06-29 23:48:05 +02:00
|
|
|
if currVign == "END":
|
|
|
|
return story
|
2019-09-17 00:20:30 +02:00
|
|
|
story[nvign]+=".png"
|
2019-09-09 17:32:07 +02:00
|
|
|
nvign +=1
|
2020-06-29 23:48:05 +02:00
|
|
|
print("tree with no END")
|
|
|
|
quit()
|
2019-09-09 17:32:07 +02:00
|
|
|
|
2020-12-17 01:31:57 +01:00
|
|
|
def addThing(indVign,config):
|
2019-09-24 13:26:31 +02:00
|
|
|
"""This function adds a small image (object) to a larger image
|
|
|
|
obj.csv definition is: name of the image (i.e. A001.png), x-coord, y-coord, subsequent columns possible outcomes
|
|
|
|
It returns a tuple (object file name, x, y)"""
|
2020-12-17 20:09:34 +01:00
|
|
|
with open(config["csvLocation"]+"/"+config["csvObj"]) as obj:
|
2019-09-17 16:33:43 +02:00
|
|
|
csvReader = csv.reader(obj)
|
|
|
|
for row in csvReader:
|
|
|
|
if row[0] == indVign:
|
|
|
|
return row[random.randint(3,len(row)-1)],row[1],row[2]
|
|
|
|
return 0
|
2019-09-13 16:08:09 +02:00
|
|
|
|
2020-12-17 01:31:57 +01:00
|
|
|
def writeStrip(story,fontSize,config):
|
2019-09-24 13:26:31 +02:00
|
|
|
"""This function creates the strip returning an image object that could be saved or viewed. It takes an array with filenames as parameter
|
2020-11-24 02:30:42 +01:00
|
|
|
The first image is always 000, then appends to strip the files, then decorates it fetching text and adding objects. If the object is an R, then
|
|
|
|
repeats the last object."""
|
2019-09-17 00:20:30 +02:00
|
|
|
strip = []
|
2019-09-12 19:53:57 +02:00
|
|
|
for indVign in story:
|
2020-06-29 23:48:05 +02:00
|
|
|
try:
|
2020-12-17 01:31:57 +01:00
|
|
|
vign = Image.open(config["imagesLocation"]+"/"+indVign).convert('RGBA')
|
2019-09-12 19:53:57 +02:00
|
|
|
addtext = ImageDraw.Draw(vign)
|
2020-12-17 01:31:57 +01:00
|
|
|
fnt = ImageFont.truetype(config["font"],fontSize)
|
|
|
|
textVign = fetchText(indVign,config)
|
2019-10-28 23:56:31 +01:00
|
|
|
|
2020-12-02 02:14:20 +01:00
|
|
|
if textVign!=0:
|
|
|
|
for x in range(len(textVign[0])):
|
|
|
|
text_vign = textVign[1][x]
|
|
|
|
while text_vign.find('$') != -1:
|
2020-12-17 01:31:57 +01:00
|
|
|
text_vign = replaceText(text_vign,config)
|
2020-12-02 02:14:20 +01:00
|
|
|
text_vign = text_vign.replace('@','\n')
|
|
|
|
addtext.multiline_text((int(textVign[0][x][0]),int(textVign[0][x][1])),text_vign,fill="#000000",font=fnt,align="center")
|
|
|
|
|
2020-12-17 01:31:57 +01:00
|
|
|
obj = addThing(indVign,config)
|
2019-09-17 16:33:43 +02:00
|
|
|
if obj!=0:
|
2020-11-24 02:30:42 +01:00
|
|
|
if obj[0] == 'R':
|
2020-12-17 01:31:57 +01:00
|
|
|
objImg = Image.open(config["imagesLocation"]+"/"+prevObj[0])
|
2020-11-24 02:30:42 +01:00
|
|
|
else:
|
|
|
|
prevObj = obj
|
2020-12-17 01:31:57 +01:00
|
|
|
objImg = Image.open(config["imagesLocation"]+"/"+obj[0])
|
2019-09-17 16:33:43 +02:00
|
|
|
vign.paste(objImg,(int(obj[1]),int(obj[2])))
|
2019-09-17 00:20:30 +02:00
|
|
|
strip.append(vign)
|
2020-06-29 23:48:05 +02:00
|
|
|
except FileNotFoundError:
|
|
|
|
pass
|
2020-12-17 02:48:30 +01:00
|
|
|
image = Image.new('RGBA',(config["xSize"],config["ySize"]))
|
2019-09-17 00:20:30 +02:00
|
|
|
xshift=0
|
|
|
|
for vign in strip:
|
|
|
|
image.paste(vign,(xshift,0))
|
2020-12-17 02:48:30 +01:00
|
|
|
xshift += config["panelLength"]
|
2019-09-17 00:20:30 +02:00
|
|
|
return image
|
2019-09-09 17:32:07 +02:00
|
|
|
|
2020-12-17 01:31:57 +01:00
|
|
|
def createStrip(config,specialPlatform="",fontSize=22):
|
2019-09-24 13:26:31 +02:00
|
|
|
"""Create strip and save it
|
|
|
|
createStrip(str path/filename)"""
|
2019-09-19 01:59:13 +02:00
|
|
|
try:
|
2020-12-17 01:31:57 +01:00
|
|
|
story = fetchVign(config)
|
|
|
|
finalStrip = writeStrip(story,fontSize,config)
|
|
|
|
if specialPlatform == "android":
|
2019-12-23 17:50:59 +01:00
|
|
|
return finalStrip
|
|
|
|
else:
|
2020-12-17 01:31:57 +01:00
|
|
|
finalStrip.save(config["saveLocation"]+config["filename"])
|
2019-12-23 17:50:59 +01:00
|
|
|
return 0
|
2019-09-19 01:59:13 +02:00
|
|
|
except Exception as err:
|
|
|
|
return err
|
|
|
|
|
2020-12-17 01:31:57 +01:00
|
|
|
def readConfig(profile=False,platform=False):
|
|
|
|
"""Read configuration file"""
|
|
|
|
try:
|
|
|
|
with open(fileDir+"/config.json") as f:
|
|
|
|
config = json.load(f)
|
|
|
|
except IOError:
|
|
|
|
print("config.json not found")
|
|
|
|
return False
|
|
|
|
if not(profile):
|
|
|
|
profile = config["defaultProfile"]
|
|
|
|
else:
|
|
|
|
profile = profile[0]
|
|
|
|
try:
|
|
|
|
checkProfile = config[profile]
|
|
|
|
except KeyError:
|
|
|
|
print("Profile not found")
|
|
|
|
quit()
|
|
|
|
saveLocation = checkLocal(config[profile]["saveLocation"])
|
|
|
|
imagesLocation = checkLocal(config[profile]["imagesLocation"])
|
|
|
|
csvLocation = checkLocal(config[profile]["csvLocation"])
|
2020-12-17 20:09:34 +01:00
|
|
|
csvTree = config[profile]["csvTree"]
|
|
|
|
csvSpeech = config[profile]["csvSpeech"]
|
|
|
|
csvSubs = config[profile]["csvSubs"]
|
|
|
|
csvObj = config[profile]["csvObj"]
|
2020-12-17 01:31:57 +01:00
|
|
|
font = checkLocal(config[profile]["font"])
|
2020-12-17 02:48:30 +01:00
|
|
|
xSize = config[profile]["xSize"]
|
|
|
|
ySize = config[profile]["ySize"]
|
|
|
|
panelLength = config[profile]["panelLength"]
|
2020-12-17 01:31:57 +01:00
|
|
|
if platform:
|
|
|
|
token = checkLocal(config[profile][platform]["token"])
|
|
|
|
filename = checkLocal(config[profile][platform]["filename"])
|
2020-12-17 20:09:34 +01:00
|
|
|
return {"saveLocation":saveLocation,"imagesLocation":imagesLocation,"csvLocation":csvLocation,"font":font,"token":token,"filename":filename,"xSize":xSize,"ySize":ySize,"panelLength":panelLength,"csvTree":csvTree,"csvSpeech":csvSpeech,"csvSubs":csvSubs,"csvObj":csvObj}
|
2020-12-17 01:31:57 +01:00
|
|
|
filename = config[profile]["filename"]
|
2020-12-17 20:09:34 +01:00
|
|
|
return {"saveLocation":saveLocation,"imagesLocation":imagesLocation,"csvLocation":csvLocation,"font":font,"filename":filename,"xSize":xSize,"ySize":ySize,"panelLength":panelLength,"csvTree":csvTree,"csvSpeech":csvSpeech,"csvSubs":csvSubs,"csvObj":csvObj}
|
2020-12-17 01:31:57 +01:00
|
|
|
|
|
|
|
def checkLocal(directory):
|
|
|
|
"""Checks if it's a relative or absolute path"""
|
|
|
|
if directory[0] == ".":
|
|
|
|
return fileDir + directory[1:]
|
|
|
|
else:
|
|
|
|
return directory
|
|
|
|
|
|
|
|
|
2019-09-09 17:32:07 +02:00
|
|
|
if __name__ == "__main__":
|
2020-02-28 17:34:49 +01:00
|
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser()
|
|
|
|
parser.add_argument('-s','--story',metavar='story',default='',nargs=4,help='name of the images')
|
2020-12-02 02:14:20 +01:00
|
|
|
parser.add_argument('-m','--multiple',metavar='multiple',default=[1],nargs=1,type=int,help='multiple output (int >0)')
|
2020-12-05 18:43:38 +01:00
|
|
|
parser.add_argument('-x','--xsize',metavar='xsize',default=0,type=int,nargs=1,help='resize image x')
|
2020-12-17 01:31:57 +01:00
|
|
|
parser.add_argument('-p','--profile',metavar='profile',default="",type=str,nargs=1,help='profile')
|
2020-02-28 17:34:49 +01:00
|
|
|
args = parser.parse_args()
|
2020-12-01 00:17:55 +01:00
|
|
|
if args.multiple[0] <= 0:
|
|
|
|
quit()
|
2020-12-17 01:31:57 +01:00
|
|
|
config = readConfig(profile=args.profile)
|
2020-12-01 00:17:55 +01:00
|
|
|
for x in range(0,args.multiple[0]):
|
|
|
|
if (args.story == ''):
|
2020-12-17 01:31:57 +01:00
|
|
|
story = fetchVign(config)
|
2020-12-01 00:17:55 +01:00
|
|
|
else:
|
|
|
|
story = []
|
|
|
|
for x in args.story:
|
|
|
|
story.append(x)
|
2020-12-17 01:31:57 +01:00
|
|
|
finalStrip = writeStrip(story,22,config)
|
2020-12-01 00:17:55 +01:00
|
|
|
if args.multiple[0] == 1:
|
2020-12-05 18:43:38 +01:00
|
|
|
if args.xsize == 0:
|
|
|
|
finalStrip.show()
|
|
|
|
else:
|
|
|
|
finalStrip.resize((args.xsize[0],int(args.xsize[0]/2400*500))).show()
|