Spaces:
Sleeping
Sleeping
| 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.") | |