Spaces:
Sleeping
Sleeping
import streamlit as st | |
import os | |
from PIL import Image | |
import base64 | |
from io import BytesIO | |
# Adjust Streamlit layout to wide mode | |
st.set_page_config(layout="wide") | |
# Generate Map as an Image | |
def generate_map(image_files, canvas_size=(3000, 3000)): | |
canvas = Image.new("RGBA", canvas_size, "white") | |
if not image_files: | |
return canvas | |
grid_size = int(len(image_files) ** 0.5) + 1 # Calculate grid size | |
img_size = canvas_size[0] // grid_size # Size for each image cell | |
for idx, img_file in enumerate(image_files): | |
img_path = os.path.join(map_dir, img_file) | |
with Image.open(img_path) as img: | |
# Maintain aspect ratio | |
img.thumbnail((img_size, img_size), Image.Resampling.LANCZOS) | |
# Calculate grid position | |
row, col = divmod(idx, grid_size) | |
x = col * img_size | |
y = row * img_size | |
# Paste the image on the canvas | |
canvas.paste(img, (x, y), mask=img if img.mode == "RGBA" else None) | |
return canvas | |
# Encode Image as Base64 for Leaflet | |
def encode_image_to_base64(image): | |
buffer = BytesIO() | |
image.save(buffer, format="PNG") | |
encoded = base64.b64encode(buffer.getvalue()).decode() | |
return encoded | |
# Directory for images | |
map_dir = "." # Replace with your directory containing images | |
image_files = [f for f in os.listdir(map_dir) if f.endswith(".png")] | |
# Generate the map | |
canvas_size = (3000, 3000) | |
canvas = generate_map(image_files, canvas_size) | |
encoded_image = encode_image_to_base64(canvas) | |
# Leaflet HTML Template | |
leaflet_html = f""" | |
<!DOCTYPE html> | |
<html> | |
<head> | |
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" /> | |
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script> | |
<style> | |
#map {{ | |
height: 100vh; | |
}} | |
</style> | |
</head> | |
<body> | |
<div id="map"></div> | |
<script> | |
// Initialize the map | |
var map = L.map('map').setView([0, 0], 1); | |
// Add the image overlay | |
var bounds = [[-1500, -1500], [1500, 1500]]; | |
var image = L.imageOverlay("data:image/png;base64,{encoded_image}", bounds).addTo(map); | |
// Set the map view to the bounds of the image | |
map.fitBounds(bounds); | |
// Add zoom controls | |
L.control.zoom({{ | |
position: 'topright' | |
}}).addTo(map); | |
</script> | |
</body> | |
</html> | |
""" | |
# Embed Leaflet Map in Streamlit | |
st.title("Interactive Dungeon Map") | |
st.components.v1.html(leaflet_html, height=600) | |