|
@@ -6,31 +6,14 @@ from pathlib import Path
|
|
|
from typing import List, Tuple
|
|
|
from PIL import Image
|
|
|
import streamlit as st
|
|
|
+import base64
|
|
|
|
|
|
-st.set_page_config(
|
|
|
- page_title="MRI physics based augmentation",
|
|
|
- page_icon="🧠",
|
|
|
- layout="wide"
|
|
|
-)
|
|
|
-
|
|
|
-# ---------- Simple router in session_state ----------
|
|
|
-if "page" not in st.session_state:
|
|
|
- st.session_state.page = "home"
|
|
|
|
|
|
-# storage for generated phantom (appears after progress completes)
|
|
|
-if "phantom_blob" not in st.session_state:
|
|
|
- st.session_state.phantom_blob = None
|
|
|
-if "phantom_name" not in st.session_state:
|
|
|
- st.session_state.phantom_name = None
|
|
|
|
|
|
def nav_to(p: str):
|
|
|
st.session_state.page = p
|
|
|
|
|
|
-st.title("MRI physics based augmentation")
|
|
|
-
|
|
|
# ---------- Theme-aware logo (top-right, base64-embedded) ----------
|
|
|
-import base64
|
|
|
-
|
|
|
def _b64_img(path: str) -> str | None:
|
|
|
try:
|
|
|
with open(path, "rb") as f:
|
|
@@ -38,52 +21,74 @@ def _b64_img(path: str) -> str | None:
|
|
|
except Exception:
|
|
|
return None
|
|
|
|
|
|
-def render_theme_logo(light_path: str = "logos/NEW_PHYSTECH_for_light.png",
|
|
|
- dark_path: str = "logos/NEW_PHYSTECH_for_dark.png",
|
|
|
- size_px: int = 250):
|
|
|
- """
|
|
|
- Рисует фиксированный логотип справа сверху, меняющийся по теме.
|
|
|
- Картинки вшиваются через base64, чтобы избежать проблем с путями.
|
|
|
- """
|
|
|
+def header_with_theme_logo(title: str,
|
|
|
+ light_path: str = "logos/NEW_PHYSTECH_for_light.png",
|
|
|
+ dark_path: str = "logos/NEW_PHYSTECH_for_dark.png",
|
|
|
+ size_px: int = 100):
|
|
|
light_b64 = _b64_img(light_path)
|
|
|
dark_b64 = _b64_img(dark_path)
|
|
|
-
|
|
|
- # Если нет файлов, просто ничего не рисуем (и даём подсказку внизу страницы)
|
|
|
- if not light_b64 and not dark_b64:
|
|
|
+ if not (light_b64 or dark_b64):
|
|
|
+ # если нет логотипов — просто выводим заголовок
|
|
|
+ st.markdown(f"## {title}")
|
|
|
return
|
|
|
|
|
|
light_src = f"data:image/png;base64,{light_b64}" if light_b64 else ""
|
|
|
- dark_src = f"data:image/png;base64,{dark_b64}" if dark_b64 else light_src
|
|
|
+ dark_src = f"data:image/png;base64,{dark_b64}" if dark_b64 else light_src
|
|
|
|
|
|
html = f"""
|
|
|
- <style>
|
|
|
- .theme-logo-topright {{
|
|
|
- position: fixed; top: 10px; right: 16px; z-index: 9999;
|
|
|
- }}
|
|
|
- .theme-logo-topright img {{
|
|
|
- width: {size_px}px; height: {size_px}px; object-fit: contain;
|
|
|
- border-radius: 8px;
|
|
|
- }}
|
|
|
- /* скрываем одну из картинок в зависимости от темы ОС/браузера */
|
|
|
- .theme-logo-topright img.light {{ display: inline-block; }}
|
|
|
- .theme-logo-topright img.dark {{ display: none; }}
|
|
|
- @media (prefers-color-scheme: dark) {{
|
|
|
- .theme-logo-topright img.light {{ display: none; }}
|
|
|
- .theme-logo-topright img.dark {{ display: inline-block; }}
|
|
|
- }}
|
|
|
- @media (max-width: 480px) {{
|
|
|
- .theme-logo-topright img {{ width: {int(size_px*0.85)}px; height: {int(size_px*0.85)}px; }}
|
|
|
- }}
|
|
|
- </style>
|
|
|
- <div class="theme-logo-topright">
|
|
|
- <img src="{light_src}" alt="logo" class="light" />
|
|
|
- <img src="{dark_src}" alt="logo" class="dark" />
|
|
|
- </div>
|
|
|
- """
|
|
|
+ <style>
|
|
|
+ /* убираем стандартный padding контейнера Streamlit сверху */
|
|
|
+ section.main > div:first-child {{
|
|
|
+ padding-top: 0rem;
|
|
|
+ }}
|
|
|
+ .hdr {{
|
|
|
+ display: flex; align-items: center; justify-content: space-between;
|
|
|
+ }}
|
|
|
+ .hdr h1 {{
|
|
|
+ margin: 0;
|
|
|
+ font-size: 3.5rem;
|
|
|
+ line-height: 1.2;
|
|
|
+ }}
|
|
|
+ .hdr .logo img {{
|
|
|
+ width: 250px; height: {size_px}px; object-fit: contain;
|
|
|
+ border-radius: 8px;
|
|
|
+ display: inline-block;
|
|
|
+ }}
|
|
|
+ .hdr .logo img.light {{ display: inline-block; }}
|
|
|
+ .hdr .logo img.dark {{ display: none; }}
|
|
|
+ @media (prefers-color-scheme: dark) {{
|
|
|
+ .hdr .logo img.light {{ display: none; }}
|
|
|
+ .hdr .logo img.dark {{ display: inline-block; }}
|
|
|
+ }}
|
|
|
+ </style>
|
|
|
+ <div class="hdr">
|
|
|
+ <h1>{title}</h1>
|
|
|
+ <div class="logo">
|
|
|
+ <img src="{light_src}" alt="logo" class="light" />
|
|
|
+ <img src="{dark_src}" alt="logo" class="dark" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ """
|
|
|
st.markdown(html, unsafe_allow_html=True)
|
|
|
|
|
|
|
|
|
-render_theme_logo()
|
|
|
+st.set_page_config(
|
|
|
+ page_title="MRI physics based augmentation",
|
|
|
+ page_icon="🧠",
|
|
|
+ layout="wide"
|
|
|
+)
|
|
|
+header_with_theme_logo("MRI physics based augmentation")
|
|
|
+
|
|
|
+# ---------- Simple router in session_state ----------
|
|
|
+if "page" not in st.session_state:
|
|
|
+ st.session_state.page = "home"
|
|
|
+
|
|
|
+# storage for generated phantom (appears after progress completes)
|
|
|
+if "phantom_blob" not in st.session_state:
|
|
|
+ st.session_state.phantom_blob = None
|
|
|
+if "phantom_name" not in st.session_state:
|
|
|
+ st.session_state.phantom_name = None
|
|
|
+
|
|
|
|
|
|
|
|
|
# ---------- Image helpers ----------
|
|
@@ -176,7 +181,8 @@ def page_home():
|
|
|
cols = st.columns(len(images))
|
|
|
for (img, name), col in zip(images, cols):
|
|
|
with col:
|
|
|
- st.image(img, caption=name, use_container_width=False)
|
|
|
+ st.image(img, use_container_width=False)
|
|
|
+ # st.image(img, caption=name, use_container_width=False)
|
|
|
else:
|
|
|
st.info("Положите 1–3 изображения в папку `assets/` (png/jpg/tif), и они появятся здесь одинакового размера.")
|
|
|
|