|
| 1 | +import PySimpleGUI as gui |
| 2 | +from PIL import Image |
| 3 | +import re |
| 4 | +import os |
| 5 | + |
| 6 | +title = "DungeonFog Map Tile Assembler" |
| 7 | +gui.theme("DarkAmber") |
| 8 | + |
| 9 | +# default_dir = os.getcwd() |
| 10 | +default_dir = "E:/Core - Development/Python/SingleFiles/DungeonFogTileAssembler/map" |
| 11 | + |
| 12 | +# default_text = "Choose a directory" |
| 13 | +default_text = default_dir |
| 14 | + |
| 15 | +layout = [ |
| 16 | + [gui.Text(title)], |
| 17 | + [], |
| 18 | + [gui.InputText(default_text, key="-INPUT-", expand_x=True)], |
| 19 | + [gui.FolderBrowse("Browse", key="-DIRECTORY-", initial_folder=default_dir, enable_events=True)], |
| 20 | + [gui.Text("", key="-OUTPUT-", text_color="red")], |
| 21 | + [gui.Button("Start", key="-START-")] |
| 22 | +] |
| 23 | + |
| 24 | +w = gui.Window(title, layout, size=(600, 180), resizable=True) |
| 25 | + |
| 26 | +while True: |
| 27 | + event, values = w.read() |
| 28 | + if event in (gui.WIN_CLOSED, "Cancel"): |
| 29 | + break |
| 30 | + elif event == "-DIRECTORY-": |
| 31 | + w['-INPUT-'].Update(values['-DIRECTORY-']) |
| 32 | + elif event == "-START-": |
| 33 | + path = values['-INPUT-'] |
| 34 | + if not os.path.isdir(path): |
| 35 | + w['-OUTPUT-'].Update("Path is not a directory.") |
| 36 | + else: |
| 37 | + w['-OUTPUT-'].Update("") |
| 38 | + maps = {} |
| 39 | + pattern = re.compile("(.*)_tile_\d+_(\d+),(\d+)$") |
| 40 | + for f in os.listdir(path): |
| 41 | + name, ext = os.path.splitext(f) |
| 42 | + # print(name) |
| 43 | + matches = pattern.findall(name) |
| 44 | + if len(matches) == 0: |
| 45 | + print("No matches in filename '" + f + "'") |
| 46 | + else: |
| 47 | + matches = matches[0] |
| 48 | + # print(matches) |
| 49 | + map_name = matches[0] |
| 50 | + x = int(matches[1]) |
| 51 | + y = int(matches[2]) |
| 52 | + if not maps.keys().__contains__(map_name): |
| 53 | + maps[map_name] = [] |
| 54 | + maps[map_name].append({ "x": x, "y": y, "filename": f, "name": name, "ext": ext }) |
| 55 | + # print(maps) |
| 56 | + |
| 57 | + for map in maps: |
| 58 | + tiles = {} |
| 59 | + ext = None |
| 60 | + for tile in maps[map]: |
| 61 | + if ext is None: |
| 62 | + ext = tile['ext'] |
| 63 | + image = Image.open(os.path.join(path, tile['filename'])) |
| 64 | + tiles[(tile['x'],tile['y'])] = image |
| 65 | + print(tiles) |
| 66 | + max_x = max(x for x, y in tiles.keys()) |
| 67 | + max_y = max(y for x, y in tiles.keys()) |
| 68 | + width, height = tiles[(1, 1)].size |
| 69 | + print(width, height) |
| 70 | + |
| 71 | + total_width = width * max_x |
| 72 | + total_height = height * max_y |
| 73 | + print(total_width, total_height) |
| 74 | + assembled_map = Image.new("RGB", (total_width, total_height)) |
| 75 | + for x in range(max_x + 1): |
| 76 | + for y in range(max_y + 1): |
| 77 | + image = tiles.get((x, y)) |
| 78 | + if image is not None: |
| 79 | + x_pos = (x-1) * width |
| 80 | + y_pos = (y-1) * height |
| 81 | + assembled_map.paste(image, (x_pos, y_pos)) |
| 82 | + output_path = os.path.join(path, "output") |
| 83 | + if not os.path.exists(output_path): |
| 84 | + os.mkdir(output_path) |
| 85 | + assembled_map.save(os.path.join(output_path, map + ext)) |
0 commit comments