Generating a tile sheet from many images
Using isometric image assets that correlate to 3D models to create a 3D environment with. The assets used are from Kenney.
Cropping and adding multiple images into a tileset is inefficient and time-consuming. I decided to write a Python script that automates this.



The script imports Image for writing, cropping and creating images and ElementTree to read, edit and create XML files that create a file describing every tile and their names in the Tiled format.
Combining and cropping images in a folder to one sprite-sheet, based on known valuesfrom PIL import Image import xml.etree.ElementTree as ET import xml.dom.minidom import os.path, sys import math path = "C:\\Users\\Dion-\\Documents\\Development\\Tiled\\TestAssets" newpath = path + "\\exported\\" dirs = os.listdir(path) # Setting the points for cropped image left = 191 top = 181 right = 130 bottom = 168 #image related imgWidth, imgHeight = Image.open( os.path.join( path, dirs[0] ) ).crop((left, top, right + left, bottom + top)).size print( "Image size: " + str(imgWidth) + ", " + str(imgHeight) ) #tileset related columns = 24 rows = math.floor( len(dirs) / columns ) + 1 spacing = 5 tilesetWidth = ( imgWidth + spacing ) * columns tilesetHeight = ( imgHeight + spacing ) * rows tilesetWidth = round(tilesetWidth) tilesetHeight = round(tilesetHeight) imgTileset = Image.new('RGBA', (tilesetWidth, tilesetHeight)) def cropAllToTileset(): itemCount = 0 curCol = 0 curRow = 0 dom_tileset = ET.Element('tileset') for item in dirs: fullpath = os.path.join(path, item) if os.path.isfile(fullpath): im = Image.open(fullpath) f, e = os.path.splitext(fullpath) imCrop = im.crop((left, top, right + left, bottom + top)) imgTileset.paste( imCrop.copy(), ((imgWidth + spacing) * curCol, (imgHeight + spacing) * curRow) ) #construct dom dom_tile = ET.SubElement(dom_tileset, 'tile') dom_tile.set('id', str(itemCount)) dom_properties = ET.SubElement(dom_tile, 'properties') dom_property = ET.SubElement(dom_properties, 'property') dom_property.set('name', 'obj_name') dom_property.set('value', os.path.basename(f)) itemCount += 1 # count correct rows for tileset if (itemCount % columns) == 0: curRow += 1 curCol = 0 else: curCol += 1 if not os.path.exists(newpath + "\\tileset\\"): os.makedirs(newpath + "\\tileset\\") #write image imgTileset.save( newpath + "\\tileset\\" + "tileset_" + str(imgWidth) + "x" + str(imgHeight) + ".png" , "png", quality=100 ) #write dom xml mydata = '<root>' + str(ET.tostring(dom_tileset, encoding='utf-8', method='xml')) + '</root>' myfile = open(newpath + "\\tileset\\" + "items2.xml", "w") dom_final = xml.dom.minidom.parseString(mydata).toprettyxml() myfile.write(dom_final) print("Done") # https://stackoverflow.com/questions/47785918/python-pil-crop-all-images-in-a-folder def crop(): for item in dirs: fullpath = os.path.join(path, item) if os.path.isfile(fullpath): im = Image.open(fullpath) f, e = os.path.splitext(fullpath) imCrop = im.crop((left, top, right + left, bottom + top)) if not os.path.exists(newpath): os.makedirs(newpath) imCrop.save( newpath + os.path.basename(f) + ".png", "png", quality=100 ) #crop() cropAllToTileset()