diff --git a/chaospuzzles/puzzle.py b/chaospuzzles/puzzle.py index 7330f35..32daaff 100644 --- a/chaospuzzles/puzzle.py +++ b/chaospuzzles/puzzle.py @@ -2,8 +2,11 @@ import os import json from flask import Blueprint, render_template + bp = Blueprint("puzzle", __name__, url_prefix="/") +root = "chaospuzzles" + def list_folders(path): """Return all the folders in a folder""" @@ -18,12 +21,18 @@ def list_folders(path): @bp.route("/") def home(): - puzzles = list_folders("chaospuzzles/puzzles") + puzzles = list_folders(f"{root}/puzzles") return render_template("home.html", puzzles=puzzles) @bp.route("/") def puzzle(puzzle=None): - with open(f"chaospuzzles/puzzles/{puzzle}/info.json") as data: + with open(f"{root}/puzzles/{puzzle}/info.json") as data: info = json.load(data) + + if info["width"] >= info["height"]: + info["ratio"] = info["width"] / info["height"] + else: + info["ratio"] = info["height"] / info["width"] + return render_template("puzzle.html", puzzle=puzzle, **info) diff --git a/chaospuzzles/puzzles/katamari/info.json b/chaospuzzles/puzzles/katamari/info.json deleted file mode 100644 index 2889b02..0000000 --- a/chaospuzzles/puzzles/katamari/info.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "katamari", - "rows": 10, - "columns": 15, - "width": 1280, - "height": 720, - "image": "katamari.jpg", - "clusters": [] -} \ No newline at end of file diff --git a/chaospuzzles/split.py b/chaospuzzles/split.py new file mode 100644 index 0000000..b88d034 --- /dev/null +++ b/chaospuzzles/split.py @@ -0,0 +1,142 @@ +import os, json +from wand.image import Image +from wand.drawing import Drawing +from shortuuid import uuid +from math import sqrt + + +def split(image, width, height, pieces): + + image_file = os.path.basename(image) + name = os.path.splitext(image_file)[0] + output = f"chaospuzzles/puzzles/{name}" + + print(f"Creating the {name} folder") + try: + os.makedirs(output) + os.makedirs(f"{output}/pieces") + os.makedirs(f"{output}/clusters") + except OSError: + pass + + print("Calculating rows and columns... ", end="") + piece_side, rows, columns = area_to_pieces(width, height, pieces) + print(f"Done!") + print(f"{rows * columns} pieces, {rows} rows by {columns} columns") + + print("Splitting in tiles... ", end="") + # copy the source image to the puzzles folder and split it into tiles + with Image(filename=image) as img: + img.save(filename=f"{output}/{image_file}") + for y in range(columns): + for x in range(rows): + x_start = x * piece_side + y_start = y * piece_side + x_end = x_start + piece_side + y_end = y_start + piece_side + with img[x_start:x_end, y_start:y_end] as piece: + piece.save(filename=f"{output}/pieces/{name}-{x}-{y}.jpg") + print("Done!") + # create an id for each piece and store it into a pieces.json file and generate the retro image for the puzzle + + print("Calculating the ID for each piece... ", end="") + pieces = [] + with Image(width=width, height=height) as retro: + draw = Drawing() + draw.font_size = 11 + draw.text_alignment = "center" + + for x in range(rows): + row = [] + for y in range(columns): + + # generate a random ID for each piece + ID = uuid()[:4] + + # write the id in the center of each piece + draw.text( + int(x * piece_side + piece_side / 2), + int(y * piece_side + piece_side / 2), + f"{name}\n{ID}", + ) + + # store the id in the pieces dictionary + row.append(ID) + pieces.append(row) + print("Done!") + print("Generating the picture to print behind the puzzle... ", end="") + draw(retro) + retro.save(filename=f"{output}/{name}_retro.png") + print("Done!") + + print("Writing pieces.json ", end="") + with open(f"{output}/pieces.json", "w") as file: + file.write(json.dumps(pieces)) + print("Done!") + + print("Writing adjacents.json ", end="") + adjacents = {} + for x in range(rows): + for y in range(columns): + current = pieces[x][y] + + if y > 0: + n = pieces[x][y - 1] + else: + n = None + + if y < columns - 1: + s = pieces[x][y + 1] + else: + s = None + + if x > 0: + w = pieces[x - 1][y] + else: + w = None + + if x < rows - 1: + e = pieces[x + 1][y] + else: + e = None + + adjacents[current] = (n, e, s, w) + + with open(f"{output}/adjacents.json", "w") as file: + file.write(json.dumps(adjacents)) + print("Done!") + + # info.json file with all the info about the puzzle + print("Writing info.json ", end="") + with open(f"{output}/info.json", "w") as file: + file.write( + json.dumps( + { + "name": name, + "rows": rows, + "columns": columns, + "width": width, + "height": height, + "image": image_file, + } + ) + ) + print("Done!") + + +def area_to_pieces(width, height, pieces): + area = width * height + piece_area = area / pieces + piece_side = sqrt(piece_area) + pieces_h = int(width / piece_side) + pieces_v = int(height / piece_side) + return (int(piece_side), pieces_h, pieces_v) + + +# test +split( + "chaospuzzles/static/img/katamari.jpg", + 3368, # width + 2380, # height + 500, # pieces +) diff --git a/chaospuzzles/split_tiles.py b/chaospuzzles/split_tiles.py deleted file mode 100644 index 5989778..0000000 --- a/chaospuzzles/split_tiles.py +++ /dev/null @@ -1,34 +0,0 @@ -from wand.image import Image -from math import floor -import os - - -def split(image, name, output, width, height, rows, columns): - - try: - os.makedirs(output) - except OSError: - pass - - piece_width = floor(width / columns) - piece_height = floor(height / rows) - with Image(filename=image) as img: - for y in range(0, columns): - for x in range(0, rows): - x_start = x * piece_width - y_start = y * piece_height - x_end = x_start + piece_width - y_end = y_start + piece_height - with img[x_start:x_end, y_start:y_end] as piece: - piece.save(filename=f"{output}/{name}-{x}-{y}.jpg") - - -split( - "chaospuzzles/puzzles/katamari/katamari.jpg", - "katamari", - "chaospuzzles/static/puzzles/katamari/pieces", - 3368, - 2380, - 10, - 14, -) diff --git a/chaospuzzles/static/css/puzzle.css b/chaospuzzles/static/css/puzzle.css new file mode 100644 index 0000000..c8072a7 --- /dev/null +++ b/chaospuzzles/static/css/puzzle.css @@ -0,0 +1,14 @@ +* { + box-sizing: border-box; +} + +.puzzle { + display: inline-block; + margin: 0 auto; +} + +.piece { + display: inline-block; + background-color: springgreen; + margin: 0; +} diff --git a/chaospuzzles/puzzles/katamari/katamari.jpg b/chaospuzzles/static/img/katamari.jpg similarity index 100% rename from chaospuzzles/puzzles/katamari/katamari.jpg rename to chaospuzzles/static/img/katamari.jpg diff --git a/chaospuzzles/templates/puzzle.html b/chaospuzzles/templates/puzzle.html index d98fd0b..21e858c 100644 --- a/chaospuzzles/templates/puzzle.html +++ b/chaospuzzles/templates/puzzle.html @@ -5,20 +5,20 @@ {{puzzle}} +

{{puzzle}}

-
+
+ {% for column in range(columns) %} {% for row in range(rows) %} - +
{%endfor%} - +
- + {% endfor %}
+