File size: 3,508 Bytes
389d620
 
377a3b2
389d620
 
 
 
 
 
 
 
 
 
377a3b2
 
 
 
 
 
 
 
 
 
 
389d620
 
377a3b2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bec86a9
389d620
 
377a3b2
389d620
 
377a3b2
389d620
 
377a3b2
 
 
 
 
 
 
 
bec86a9
377a3b2
389d620
377a3b2
389d620
bec86a9
389d620
 
 
 
 
 
 
 
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
import streamlit as st
import os
from PIL import Image, ImageDraw
import random

# Function to calculate aspect ratio
def calculate_aspect_ratio(image_path):
    with Image.open(image_path) as img:
        width, height = img.size
        gcd = lambda a, b: a if not b else gcd(b, a % b)
        divisor = gcd(width, height)
        return width // divisor, height // divisor

# Function to randomly position images while ensuring no overlap
def arrange_images(image_files, output_path="dungeon_layout.png"):
    if not image_files:
        return None
    
    # Initialize variables for layout
    positions = []  # Keeps track of image positions
    canvas_size = (3000, 3000)  # Adjust based on your needs
    canvas = Image.new("RGBA", canvas_size, "white")
    draw = ImageDraw.Draw(canvas)
    
    for img_file in image_files:
        img_path = os.path.join(map_dir, img_file)
        with Image.open(img_path) as img:
            width, height = img.size
            
            # Randomly decide horizontal or vertical placement
            if random.choice(["horizontal", "vertical"]) == "horizontal":
                x_center = random.randint(width // 2, canvas_size[0] - width // 2)
                y_center = canvas_size[1] // 2
            else:
                x_center = canvas_size[0] // 2
                y_center = random.randint(height // 2, canvas_size[1] - height // 2)
            
            # Calculate position
            x1 = x_center - width // 2
            y1 = y_center - height // 2
            x2 = x1 + width
            y2 = y1 + height
            
            # Ensure no overlap with existing images
            overlap = any(
                x1 < pos[2] and x2 > pos[0] and y1 < pos[3] and y2 > pos[1]
                for pos in positions
            )
            
            if not overlap:
                positions.append((x1, y1, x2, y2))
                canvas.paste(img, (x1, y1))
                
                # Draw connection line
                if len(positions) > 1:
                    prev_x, prev_y = (positions[-2][0] + positions[-2][2]) // 2, (positions[-2][1] + positions[-2][3]) // 2
                    curr_x, curr_y = (x1 + x2) // 2, (y1 + y2) // 2
                    draw.line([(prev_x, prev_y), (curr_x, curr_y)], fill="black", width=5)

    canvas.save(output_path)
    return output_path

# Streamlit App
st.title("Dynamic Dungeon Map Generator")
st.write("Automatically generates dungeon maps by analyzing PNG images in a top-level directory.")

# Directory for images
map_dir = "."  # Top-level directory

# 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"):
        layout_image = arrange_images(image_files)
        if layout_image:
            st.image(layout_image, caption="Generated Dungeon Map Layout")
        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.")