Spaces:
Sleeping
Sleeping
File size: 4,813 Bytes
e2a4174 207e561 e2a4174 207e561 fb8aa70 207e561 fb8aa70 207e561 fb8aa70 207e561 fb8aa70 207e561 fb8aa70 207e561 e2a4174 fb8aa70 e2a4174 fb8aa70 e2a4174 fb8aa70 e2a4174 fb8aa70 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
import streamlit as st
import os
from PIL import Image
import random
from io import BytesIO
# Function to arrange images dynamically
def arrange_images(image_files, canvas_size=(3000, 3000)):
if not image_files:
return None
# Initialize layout
positions = [] # Keeps track of image positions (x1, y1, x2, y2)
canvas = Image.new("RGBA", canvas_size, "white")
def get_center(pos):
"""Calculate center of a bounding box (x1, y1, x2, y2)."""
return ((pos[0] + pos[2]) // 2, (pos[1] + pos[3]) // 2)
def does_overlap(new_box, existing_boxes):
"""Check if a new bounding box overlaps any existing boxes."""
for box in existing_boxes:
if (
new_box[0] < box[2]
and new_box[2] > box[0]
and new_box[1] < box[3]
and new_box[3] > box[1]
):
return True
return False
# Place the first image at the center of the canvas
first_img_path = os.path.join(map_dir, image_files[0])
with Image.open(first_img_path) as img:
width, height = img.size
x1 = (canvas_size[0] - width) // 2
y1 = (canvas_size[1] - height) // 2
x2, y2 = x1 + width, y1 + height
positions.append((x1, y1, x2, y2))
canvas.paste(img, (x1, y1))
# Place remaining images
for img_file in image_files[1:]:
placed = False
img_path = os.path.join(map_dir, img_file)
with Image.open(img_path) as img:
width, height = img.size
while not placed:
# Choose a random existing image to connect to
target_box = random.choice(positions)
target_center = get_center(target_box)
# Randomly choose a side of the target image
side = random.choice(["top", "bottom", "left", "right"])
# Calculate the new image's position based on the chosen side
if side == "top":
x1 = target_center[0] - width // 2
y1 = target_box[1] - height
elif side == "bottom":
x1 = target_center[0] - width // 2
y1 = target_box[3]
elif side == "left":
x1 = target_box[0] - width
y1 = target_center[1] - height // 2
elif side == "right":
x1 = target_box[2]
y1 = target_center[1] - height // 2
x2, y2 = x1 + width, y1 + height
# Check for overlap
if not does_overlap((x1, y1, x2, y2), positions):
# Place the image
positions.append((x1, y1, x2, y2))
canvas.paste(img, (x1, y1))
placed = True
# Save canvas to memory
buffer = BytesIO()
canvas.save(buffer, format="PNG")
buffer.seek(0)
return buffer
# Streamlit App
st.title("Dynamic Dungeon Map Generator")
st.write("Automatically generates dungeon maps by arranging PNG images dynamically.")
# Directory for images
map_dir = "." # Top-level directory
# Canvas size and scroll offsets
canvas_size = 3000
scroll_offset = {"x": 0, "y": 0}
# WASD Controls for scrolling
st.sidebar.title("Scroll Map")
scroll_buttons = st.sidebar.columns(3)
if scroll_buttons[0].button("⬅️"):
scroll_offset["x"] -= 100
if scroll_buttons[1].button("⬆️"):
scroll_offset["y"] -= 100
if scroll_buttons[2].button("➡️"):
scroll_offset["x"] += 100
if st.sidebar.button("⬇️"):
scroll_offset["y"] += 100
# Scan the directory for .png files
image_files = [f for f in os.listdir(map_dir) if f.endswith(".png")]
if image_files:
# Add "Create Map" button
if st.button("🗺️ Create Map"):
scroll_offset = {"x": 0, "y": 0} # Reset scroll offset
layout_image = arrange_images(image_files, canvas_size=(canvas_size, canvas_size))
if layout_image:
st.image(
layout_image,
caption="Generated Dungeon Map Layout",
use_container_width=True,
output_format="PNG",
clamp=True
)
else:
st.write("Failed to generate a map. Please check the images in the directory.")
else:
st.write("No PNG files found in the top-level directory.")
# Sidebar for file upload
st.sidebar.title("Options")
uploaded_file = st.sidebar.file_uploader("Upload a PNG file", type="png")
if uploaded_file:
# Save uploaded file to the directory
with open(os.path.join(map_dir, uploaded_file.name), "wb") as f:
f.write(uploaded_file.getbuffer())
st.sidebar.success("File uploaded successfully! Refresh the app to include it in the dungeon map.")
|