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.")