split process and puzzle template wip

master
km0 3 years ago
parent 4054257698
commit 408a27b05e

@ -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("/<puzzle>")
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)

@ -1,9 +0,0 @@
{
"name": "katamari",
"rows": 10,
"columns": 15,
"width": 1280,
"height": 720,
"image": "katamari.jpg",
"clusters": []
}

@ -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
)

@ -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,
)

@ -0,0 +1,14 @@
* {
box-sizing: border-box;
}
.puzzle {
display: inline-block;
margin: 0 auto;
}
.piece {
display: inline-block;
background-color: springgreen;
margin: 0;
}

Before

Width:  |  Height:  |  Size: 482 KiB

After

Width:  |  Height:  |  Size: 482 KiB

@ -5,20 +5,20 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{puzzle}}</title>
<link rel="stylesheet" href="{{url_for('static', filename='css/puzzle.css')}}">
</head>
<body>
<h1>{{puzzle}}</h1>
<div>
<div class="puzzle">
{% for column in range(columns) %} {% for row in range(rows) %}
<img
src="{{url_for('static', filename='puzzles/' + puzzle + '/pieces/'+ puzzle + '-' +
row|string + '-' + column|string + '.jpg')}}"
/>
<div class="piece" style="width: {{ 100 / rows }}vmin; height: {{ 100 / ratio / columns }}vmin; "></div>
{%endfor%}
<br />
{% endfor %}
</div>
</div>
</body>
</html>

Loading…
Cancel
Save