Spaces:
Sleeping
Sleeping
Upload app.py
Browse files
app.py
ADDED
@@ -0,0 +1,496 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import os
|
3 |
+
import time
|
4 |
+
import random
|
5 |
+
from PIL import Image
|
6 |
+
import glob
|
7 |
+
from streamlit_autorefresh import st_autorefresh
|
8 |
+
import base64
|
9 |
+
from streamlit.components.v1 import html
|
10 |
+
import io
|
11 |
+
|
12 |
+
# ํ์ด์ง ์ค์
|
13 |
+
st.set_page_config(
|
14 |
+
page_title="๋์คํ๋ ์ด ์ปจํ
์ธ ๊ด๋ฆฌ",
|
15 |
+
page_icon="๐ผ๏ธ",
|
16 |
+
layout="wide",
|
17 |
+
initial_sidebar_state="collapsed"
|
18 |
+
)
|
19 |
+
|
20 |
+
# CSS ์คํ์ผ ์ ์
|
21 |
+
st.markdown("""
|
22 |
+
<style>
|
23 |
+
.main-content {
|
24 |
+
padding: 0;
|
25 |
+
max-width: 100%;
|
26 |
+
}
|
27 |
+
.stApp {
|
28 |
+
margin: 0;
|
29 |
+
padding: 0;
|
30 |
+
}
|
31 |
+
|
32 |
+
/* ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง ์คํ์ผ๋ก ์์ */
|
33 |
+
.full-view {
|
34 |
+
width: 100vw;
|
35 |
+
height: 100vh;
|
36 |
+
position: fixed;
|
37 |
+
top: 0;
|
38 |
+
left: 0;
|
39 |
+
z-index: 9999;
|
40 |
+
background-color: #000;
|
41 |
+
background-size: cover;
|
42 |
+
background-position: center;
|
43 |
+
background-repeat: no-repeat;
|
44 |
+
display: flex;
|
45 |
+
flex-direction: column;
|
46 |
+
justify-content: flex-end;
|
47 |
+
align-items: flex-end;
|
48 |
+
padding: 20px;
|
49 |
+
}
|
50 |
+
|
51 |
+
/* ์ ํ ๋ฒํผ ์คํ์ผ */
|
52 |
+
.view-toggle {
|
53 |
+
background: rgba(0,0,0,0.5);
|
54 |
+
color: white;
|
55 |
+
border: none;
|
56 |
+
padding: 5px 10px;
|
57 |
+
margin: 5px;
|
58 |
+
border-radius: 4px;
|
59 |
+
cursor: pointer;
|
60 |
+
font-size: 14px;
|
61 |
+
}
|
62 |
+
|
63 |
+
/* ํ๋จ ์ปจํธ๋กค ํจ๋ */
|
64 |
+
.controls-panel {
|
65 |
+
display: flex;
|
66 |
+
gap: 10px;
|
67 |
+
margin-top: 10px;
|
68 |
+
}
|
69 |
+
|
70 |
+
/* ์ธ๋ค์ผ ์คํ์ผ */
|
71 |
+
.thumbnail-container {
|
72 |
+
display: flex;
|
73 |
+
align-items: center;
|
74 |
+
margin-bottom: 5px;
|
75 |
+
}
|
76 |
+
.thumbnail-container img {
|
77 |
+
max-width: 60px;
|
78 |
+
max-height: 60px;
|
79 |
+
object-fit: contain;
|
80 |
+
margin-right: 10px;
|
81 |
+
border-radius: 4px;
|
82 |
+
border: 1px solid #ddd;
|
83 |
+
}
|
84 |
+
|
85 |
+
/* ์ ๋๋ฉ์ด์
์์ */
|
86 |
+
@keyframes fadeIn {
|
87 |
+
0% { opacity: 0; }
|
88 |
+
100% { opacity: 1; }
|
89 |
+
}
|
90 |
+
@keyframes zoomIn {
|
91 |
+
0% { transform: scale(0.8); opacity: 0; }
|
92 |
+
100% { transform: scale(1); opacity: 1; }
|
93 |
+
}
|
94 |
+
@keyframes slideIn {
|
95 |
+
0% { transform: translateY(-50px); opacity: 0; }
|
96 |
+
100% { transform: translateY(0); opacity: 1; }
|
97 |
+
}
|
98 |
+
@keyframes rotateIn {
|
99 |
+
0% { transform: rotate(-10deg) scale(0.8); opacity: 0; }
|
100 |
+
100% { transform: rotate(0) scale(1); opacity: 1; }
|
101 |
+
}
|
102 |
+
|
103 |
+
.animate-fade {
|
104 |
+
animation: fadeIn 1s ease-out forwards;
|
105 |
+
}
|
106 |
+
.animate-zoom {
|
107 |
+
animation: zoomIn 1s ease-out forwards;
|
108 |
+
}
|
109 |
+
.animate-slide {
|
110 |
+
animation: slideIn 1s ease-out forwards;
|
111 |
+
}
|
112 |
+
.animate-rotate {
|
113 |
+
animation: rotateIn 1s ease-out forwards;
|
114 |
+
}
|
115 |
+
</style>
|
116 |
+
""", unsafe_allow_html=True)
|
117 |
+
|
118 |
+
# ์ด๊ธฐ ์ค์ ๋ฐ ์ํ ๊ด๋ฆฌ
|
119 |
+
if 'contents' not in st.session_state:
|
120 |
+
# contents ํด๋ ๋ด์ ๋ชจ๋ ์ด๋ฏธ์ง ํ์ผ ๋ก๋
|
121 |
+
if not os.path.exists('contents'):
|
122 |
+
os.makedirs('contents')
|
123 |
+
|
124 |
+
image_files = glob.glob('contents/*.jpg') + glob.glob('contents/*.jpeg') + glob.glob('contents/*.png')
|
125 |
+
st.session_state.contents = image_files
|
126 |
+
|
127 |
+
if 'current_image_index' not in st.session_state:
|
128 |
+
st.session_state.current_image_index = 0
|
129 |
+
|
130 |
+
if 'animation_type' not in st.session_state:
|
131 |
+
st.session_state.animation_type = 'animate-fade'
|
132 |
+
|
133 |
+
if 'activate_fullscreen' not in st.session_state:
|
134 |
+
st.session_state.activate_fullscreen = False
|
135 |
+
|
136 |
+
if 'fit_mode' not in st.session_state:
|
137 |
+
st.session_state.fit_mode = 'cover' # ๊ธฐ๋ณธ๊ฐ์ ํ๋ฉด์ ๊ฝ ์ฐจ๊ฒ
|
138 |
+
|
139 |
+
# ์ฌ๊ธฐ์ ์ถ๊ฐํ์ธ์!
|
140 |
+
if 'app_loaded' not in st.session_state:
|
141 |
+
st.session_state.app_loaded = False
|
142 |
+
|
143 |
+
# ์ฌ๋ผ์ด๋์ผ ์๋ ์์ ๋ก์ง
|
144 |
+
if not st.session_state.app_loaded and not st.session_state.get('preview_mode', False):
|
145 |
+
if st.session_state.contents: # ์ด๋ฏธ์ง๊ฐ ์๋ ๊ฒฝ์ฐ์๋ง ์๋ ์์
|
146 |
+
st.session_state.preview_mode = True
|
147 |
+
st.session_state.preview_start_time = time.time()
|
148 |
+
st.session_state.activate_fullscreen = True
|
149 |
+
st.session_state.app_loaded = True # ์ฑ์ด ๋ก๋๋์์์ ํ์
|
150 |
+
|
151 |
+
# ์ด๋ฏธ์ง ์ธ๋ค์ผ ์์ฑ ํจ์
|
152 |
+
def create_thumbnail(image_path, size=(60, 60)):
|
153 |
+
try:
|
154 |
+
img = Image.open(image_path)
|
155 |
+
img.thumbnail(size)
|
156 |
+
buffered = io.BytesIO()
|
157 |
+
img.save(buffered, format=img.format or "JPEG")
|
158 |
+
return buffered.getvalue()
|
159 |
+
except Exception as e:
|
160 |
+
st.error(f"์ธ๋ค์ผ ์์ฑ ์ค๋ฅ: {e}")
|
161 |
+
return None
|
162 |
+
|
163 |
+
# ์ด๋ฏธ์ง ์์ ๋ณ๊ฒฝ ํจ์๋ค
|
164 |
+
def move_up(index):
|
165 |
+
if index > 0:
|
166 |
+
st.session_state.contents[index], st.session_state.contents[index-1] = st.session_state.contents[index-1], st.session_state.contents[index]
|
167 |
+
|
168 |
+
def move_down(index):
|
169 |
+
if index < len(st.session_state.contents) - 1:
|
170 |
+
st.session_state.contents[index], st.session_state.contents[index+1] = st.session_state.contents[index+1], st.session_state.contents[index]
|
171 |
+
|
172 |
+
def move_to_top(index):
|
173 |
+
if index > 0:
|
174 |
+
item = st.session_state.contents.pop(index)
|
175 |
+
st.session_state.contents.insert(0, item)
|
176 |
+
|
177 |
+
def move_to_bottom(index):
|
178 |
+
if index < len(st.session_state.contents) - 1:
|
179 |
+
item = st.session_state.contents.pop(index)
|
180 |
+
st.session_state.contents.append(item)
|
181 |
+
|
182 |
+
# ์๋ ์ ์ฒดํ๋ฉด ๋ชจ๋๋ฅผ ์ํ JavaScript ํจ์
|
183 |
+
def inject_fullscreen_js():
|
184 |
+
js_code = """
|
185 |
+
<script>
|
186 |
+
// ์ ์ฒดํ๋ฉด ๋ชจ๋ ํ์ฑํ ํจ์
|
187 |
+
function activateFullscreen() {
|
188 |
+
// ์ ์ฒดํ๋ฉด ๋ฒํผ ์ฐพ๊ธฐ (Streamlit์ ๊ธฐ๋ณธ ์ ์ฒดํ๋ฉด ๋ฒํผ)
|
189 |
+
const fullscreenButton = window.parent.document.querySelector('button[title="View fullscreen"]');
|
190 |
+
|
191 |
+
if (fullscreenButton) {
|
192 |
+
// ๋ฒํผ์ด ์์ผ๋ฉด ํด๋ฆญ
|
193 |
+
fullscreenButton.click();
|
194 |
+
} else {
|
195 |
+
// ๋ฒํผ์ ์ฐพ์ ์ ์์ผ๋ฉด ๋ธ๋ผ์ฐ์ API ์ฌ์ฉ
|
196 |
+
var elem = document.documentElement;
|
197 |
+
if (elem.requestFullscreen) {
|
198 |
+
elem.requestFullscreen();
|
199 |
+
} else if (elem.mozRequestFullScreen) { /* Firefox */
|
200 |
+
elem.mozRequestFullScreen();
|
201 |
+
} else if (elem.webkitRequestFullscreen) { /* Chrome, Safari & Opera */
|
202 |
+
elem.webkitRequestFullscreen();
|
203 |
+
} else if (elem.msRequestFullscreen) { /* IE/Edge */
|
204 |
+
elem.msRequestFullscreen();
|
205 |
+
}
|
206 |
+
}
|
207 |
+
}
|
208 |
+
|
209 |
+
// 1์ด ํ ์ ์ฒดํ๋ฉด ํ์ฑํ
|
210 |
+
setTimeout(function() {
|
211 |
+
activateFullscreen();
|
212 |
+
}, 1000);
|
213 |
+
</script>
|
214 |
+
"""
|
215 |
+
html(js_code, height=0, width=0)
|
216 |
+
|
217 |
+
# ์ ๋๋ฉ์ด์
JS๋ฅผ ์ฃผ์
ํ๋ ํจ์
|
218 |
+
def inject_animation_js(animation_type):
|
219 |
+
js_code = f"""
|
220 |
+
<script>
|
221 |
+
// ์ ๋๋ฉ์ด์
์ ์ฉ
|
222 |
+
function applyAnimation() {{
|
223 |
+
const imageContainer = document.querySelector('.full-view img');
|
224 |
+
if (imageContainer) {{
|
225 |
+
imageContainer.classList.remove('animate-fade', 'animate-zoom', 'animate-slide', 'animate-rotate');
|
226 |
+
void imageContainer.offsetWidth; // ๊ฐ์ ๋ฆฌํ๋ก์ฐ
|
227 |
+
imageContainer.classList.add('{animation_type}');
|
228 |
+
}}
|
229 |
+
}}
|
230 |
+
|
231 |
+
// ํ์ด์ง ๋ก๋ ํ ์ ๋๋ฉ์ด์
์ ์ฉ
|
232 |
+
setTimeout(applyAnimation, 100);
|
233 |
+
</script>
|
234 |
+
"""
|
235 |
+
html(js_code, height=0, width=0)
|
236 |
+
|
237 |
+
# ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง ํ์ ๋ฐฉ์ ์ ํ์ ์ํ JavaScript ํจ์
|
238 |
+
def inject_background_toggle_js():
|
239 |
+
js_code = """
|
240 |
+
<script>
|
241 |
+
// ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง ํ์ ๋ฐฉ์ ์ ํ ํจ์
|
242 |
+
function toggleBackgroundFit() {
|
243 |
+
const fullView = document.querySelector('.full-view');
|
244 |
+
if (fullView) {
|
245 |
+
const currentFit = fullView.style.backgroundSize;
|
246 |
+
if (currentFit === 'cover') {
|
247 |
+
fullView.style.backgroundSize = 'contain';
|
248 |
+
document.getElementById('fit-toggle-btn').innerText = 'ํ๋ฉด์ ๊ฝ ์ฐจ๊ฒ';
|
249 |
+
} else {
|
250 |
+
fullView.style.backgroundSize = 'cover';
|
251 |
+
document.getElementById('fit-toggle-btn').innerText = '์๋ณธ ๋น์จ ์ ์ง';
|
252 |
+
}
|
253 |
+
}
|
254 |
+
}
|
255 |
+
|
256 |
+
// ์ ์ญ ๋ฒ์์ ํจ์ ๋
ธ์ถ (window ๊ฐ์ฒด์ ์ถ๊ฐ)
|
257 |
+
window.applyBackgroundAnimation = function(animationType) {
|
258 |
+
const fullView = document.querySelector('.full-view');
|
259 |
+
if (fullView) {
|
260 |
+
// ๋ชจ๋ ์ ๋๋ฉ์ด์
ํด๋์ค ์ ๊ฑฐ
|
261 |
+
fullView.classList.remove('animate-fade', 'animate-zoom', 'animate-slide', 'animate-rotate');
|
262 |
+
|
263 |
+
// ์ ์ ๋๋ฉ์ด์
ํด๋์ค ์ถ๊ฐ
|
264 |
+
void fullView.offsetWidth; // ๊ฐ์ ๋ฆฌํ๋ก์ฐ
|
265 |
+
fullView.classList.add(animationType);
|
266 |
+
}
|
267 |
+
}
|
268 |
+
</script>
|
269 |
+
"""
|
270 |
+
html(js_code, height=0, width=0)
|
271 |
+
|
272 |
+
|
273 |
+
# ์ฌ์ด๋๋ฐ์ ๊ด๋ฆฌ ๊ธฐ๋ฅ ์ถ๊ฐ
|
274 |
+
with st.sidebar:
|
275 |
+
st.title("์ปจํ
์ธ ๊ด๋ฆฌ")
|
276 |
+
|
277 |
+
# ์ด๋ฏธ์ง ์
๋ก๋
|
278 |
+
uploaded_files = st.file_uploader("์ด๋ฏธ์ง ์ถ๊ฐ", type=["jpg", "jpeg", "png"], accept_multiple_files=True)
|
279 |
+
if uploaded_files:
|
280 |
+
for file in uploaded_files:
|
281 |
+
# ํ์ผ ์ ์ฅ
|
282 |
+
file_path = os.path.join('contents', file.name)
|
283 |
+
with open(file_path, "wb") as f:
|
284 |
+
f.write(file.getbuffer())
|
285 |
+
|
286 |
+
# ๋ชฉ๋ก์ ์ถ๊ฐ (์ค๋ณต ํ์ธ)
|
287 |
+
if file_path not in st.session_state.contents:
|
288 |
+
st.session_state.contents.append(file_path)
|
289 |
+
|
290 |
+
st.success(f"{len(uploaded_files)}๊ฐ ์ด๋ฏธ์ง๊ฐ ์ถ๊ฐ๋์์ต๋๋ค.")
|
291 |
+
|
292 |
+
# ํ์ฌ ์ฝํ
์ธ ๋ชฉ๋ก ๋ฐ ์ญ์ ๊ธฐ๋ฅ
|
293 |
+
st.subheader("ํ์ฌ ์ปจํ
์ธ ๋ชฉ๋ก ๋ฐ ์์ ๊ด๋ฆฌ")
|
294 |
+
|
295 |
+
if not st.session_state.contents:
|
296 |
+
st.info("์ปจํ
์ธ ๊ฐ ์์ต๋๋ค. ์ด๋ฏธ์ง๋ฅผ ์ถ๊ฐํด์ฃผ์ธ์.")
|
297 |
+
else:
|
298 |
+
# ํ์ ์์ ๊ด๋ฆฌ
|
299 |
+
for i, img_path in enumerate(st.session_state.contents):
|
300 |
+
img_name = os.path.basename(img_path)
|
301 |
+
|
302 |
+
# ์ธ๋ค์ผ๊ณผ ํ์ผ๋ช
์ ํฌํจํ HTML ์์ฑ
|
303 |
+
thumbnail_data = create_thumbnail(img_path)
|
304 |
+
if thumbnail_data:
|
305 |
+
thumbnail_b64 = base64.b64encode(thumbnail_data).decode()
|
306 |
+
st.markdown(f"""
|
307 |
+
<div class="thumbnail-container">
|
308 |
+
<img src="data:image/jpeg;base64,{thumbnail_b64}" alt="{img_name}" />
|
309 |
+
<div>{i+1}. {img_name}</div>
|
310 |
+
</div>
|
311 |
+
""", unsafe_allow_html=True)
|
312 |
+
else:
|
313 |
+
st.write(f"{i+1}. {img_name}")
|
314 |
+
|
315 |
+
# ์์ ๋ฒํผ๋ค
|
316 |
+
col1, col2 = st.columns(2)
|
317 |
+
with col1:
|
318 |
+
if st.button("โ ์๋ก", key=f"up_{i}", help="ํ ์์น ์๋ก ์ด๋"):
|
319 |
+
move_up(i)
|
320 |
+
st.rerun()
|
321 |
+
|
322 |
+
with col2:
|
323 |
+
if st.button("โ ์๋๋ก", key=f"down_{i}", help="ํ ์์น ์๋๋ก ์ด๋"):
|
324 |
+
move_down(i)
|
325 |
+
st.rerun()
|
326 |
+
|
327 |
+
col3, col4 = st.columns(2)
|
328 |
+
with col3:
|
329 |
+
if st.button("โค ๋งจ์๋ก", key=f"top_{i}", help="๋งจ ์๋ก ์ด๋"):
|
330 |
+
move_to_top(i)
|
331 |
+
st.rerun()
|
332 |
+
|
333 |
+
with col4:
|
334 |
+
if st.button("โค ๋งจ์๋๋ก", key=f"bottom_{i}", help="๋งจ ์๋๋ก ์ด๋"):
|
335 |
+
move_to_bottom(i)
|
336 |
+
st.rerun()
|
337 |
+
|
338 |
+
# ์ญ์ ๋ฒํผ
|
339 |
+
if st.button("๐๏ธ ์ญ์ ", key=f"del_{i}", help="์ด๋ฏธ์ง ์ญ์ "):
|
340 |
+
if os.path.exists(img_path):
|
341 |
+
# ํ์ผ ์ญ์ ์ฌ๋ถ ํ์ธ
|
342 |
+
if st.session_state.contents.count(img_path) == 1:
|
343 |
+
os.remove(img_path)
|
344 |
+
|
345 |
+
# ๋ชฉ๋ก์์ ์ ๊ฑฐ
|
346 |
+
st.session_state.contents.remove(img_path)
|
347 |
+
|
348 |
+
# ํ์ฌ ์ด๋ฏธ์ง ์ธ๋ฑ์ค ์กฐ์
|
349 |
+
if st.session_state.current_image_index >= len(st.session_state.contents):
|
350 |
+
st.session_state.current_image_index = 0
|
351 |
+
|
352 |
+
st.rerun()
|
353 |
+
|
354 |
+
st.markdown("<hr>", unsafe_allow_html=True)
|
355 |
+
|
356 |
+
# ์ ๋๋ฉ์ด์
ํจ๊ณผ ์ ํ
|
357 |
+
st.subheader("ํ๋ฉด ์ ํ ํจ๊ณผ")
|
358 |
+
animation_options = {
|
359 |
+
"animate-fade": "ํ์ด๋ ์ธ",
|
360 |
+
"animate-zoom": "์ค ์ธ",
|
361 |
+
"animate-slide": "์ฌ๋ผ์ด๋ ์ธ",
|
362 |
+
"animate-rotate": "ํ์ ์ธ"
|
363 |
+
}
|
364 |
+
selected_animation = st.selectbox(
|
365 |
+
"ํ๋ฉด ์ ํ ์ ๋๋ฉ์ด์
",
|
366 |
+
options=list(animation_options.keys()),
|
367 |
+
format_func=lambda x: animation_options[x],
|
368 |
+
index=list(animation_options.keys()).index(st.session_state.animation_type)
|
369 |
+
)
|
370 |
+
if selected_animation != st.session_state.animation_type:
|
371 |
+
st.session_state.animation_type = selected_animation
|
372 |
+
|
373 |
+
# ์ฌ์ ์ค์
|
374 |
+
st.subheader("์ฌ์ ์ค์ ")
|
375 |
+
preview_interval = st.slider("ํ์ ๊ฐ๊ฒฉ (์ด)", 2, 10, 5)
|
376 |
+
|
377 |
+
# ํ์ ์ต์
|
378 |
+
fit_options = {"cover": "ํ๋ฉด์ ๊ฝ ์ฐจ๊ฒ", "contain": "์๋ณธ ๋น์จ ์ ์ง"}
|
379 |
+
selected_fit = st.selectbox(
|
380 |
+
"์ด๋ฏธ์ง ํ์ ๋ฐฉ์",
|
381 |
+
options=list(fit_options.keys()),
|
382 |
+
format_func=lambda x: fit_options[x],
|
383 |
+
index=list(fit_options.keys()).index(st.session_state.fit_mode)
|
384 |
+
)
|
385 |
+
if selected_fit != st.session_state.fit_mode:
|
386 |
+
st.session_state.fit_mode = selected_fit
|
387 |
+
|
388 |
+
# ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์์ ๋ฒํผ
|
389 |
+
if st.button("์ ์ฒดํ๋ฉด ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์์", use_container_width=True):
|
390 |
+
st.session_state.preview_mode = True
|
391 |
+
st.session_state.preview_start_time = time.time()
|
392 |
+
st.session_state.activate_fullscreen = True
|
393 |
+
st.rerun()
|
394 |
+
|
395 |
+
# ์ ์ฒดํ๋ฉด ๋ชจ๋ ํ์ฑํ (์กฐ๊ฑด๋ถ)
|
396 |
+
if st.session_state.get('activate_fullscreen', False):
|
397 |
+
inject_fullscreen_js()
|
398 |
+
st.session_state.activate_fullscreen = False # ํ ๋ฒ๋ง ์คํ๋๋๋ก ๋ฆฌ์
|
399 |
+
|
400 |
+
# ๋ฉ์ธ ์ปจํ
์ธ ์์ญ
|
401 |
+
if st.session_state.get('preview_mode', False):
|
402 |
+
# ์๋ ์๋ก๊ณ ์นจ์ ์ํ ์นด์ดํฐ
|
403 |
+
count = st_autorefresh(interval=preview_interval * 1000, key="refreshInterval")
|
404 |
+
|
405 |
+
# ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง ์ ํ JS ์ฝ์
(๋จผ์ ์คํ๋์ด์ผ ํจ)
|
406 |
+
inject_background_toggle_js()
|
407 |
+
|
408 |
+
# ํ์ฌ ์ธ๋ฑ์ค ์
๋ฐ์ดํธ
|
409 |
+
if count > 0 and st.session_state.contents:
|
410 |
+
st.session_state.current_image_index = (st.session_state.current_image_index + 1) % len(st.session_state.contents)
|
411 |
+
|
412 |
+
# ํ๋ฉด์ ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง๋ก ํ์
|
413 |
+
if st.session_state.contents:
|
414 |
+
full_img_path = st.session_state.contents[st.session_state.current_image_index]
|
415 |
+
|
416 |
+
# ์น์์ ์ ๊ทผ ๊ฐ๋ฅํ ์ด๋ฏธ์ง URL๋ก ๋ณํ (Base64 ์ธ์ฝ๋ฉ ์ฌ์ฉ)
|
417 |
+
with open(full_img_path, "rb") as img_file:
|
418 |
+
img_data = base64.b64encode(img_file.read()).decode()
|
419 |
+
|
420 |
+
# ์ด๋ฏธ์ง ํ์ฅ์ ๊ฐ์ ธ์ค๊ธฐ (๊ธฐ๋ณธ๊ฐ์ jpeg)
|
421 |
+
file_ext = os.path.splitext(full_img_path)[1][1:] or "jpeg"
|
422 |
+
|
423 |
+
# ๋ฐฐ๊ฒฝ ์ด๋ฏธ์ง ์ค์ ๊ณผ ์ปจํธ๋กค ๋ฒํผ์ด ํฌํจ๋ HTML ์์ฑ
|
424 |
+
background_html = f"""
|
425 |
+
<div class="full-view animate-{st.session_state.animation_type}"
|
426 |
+
style="background-image: url('data:image/{file_ext};base64,{img_data}');
|
427 |
+
background-size: {st.session_state.fit_mode};">
|
428 |
+
<div class="controls-panel">
|
429 |
+
<button id="fit-toggle-btn" class="view-toggle" onclick="toggleBackgroundFit()">
|
430 |
+
{'์๋ณธ ๋น์จ ์ ์ง' if st.session_state.fit_mode == 'cover' else 'ํ๋ฉด์ ๊ฝ ์ฐจ๊ฒ'}
|
431 |
+
</button>
|
432 |
+
<button id="exit-btn" class="view-toggle" onclick="window.location.href=window.location.pathname">
|
433 |
+
๋ฏธ๋ฆฌ๋ณด๊ธฐ ์ข
๋ฃ
|
434 |
+
</button>
|
435 |
+
</div>
|
436 |
+
</div>
|
437 |
+
<script>
|
438 |
+
// ์ ์ฒดํ๋ฉด ํ์ฑํ
|
439 |
+
setTimeout(function() {{
|
440 |
+
var elem = document.documentElement;
|
441 |
+
if (elem.requestFullscreen) {{
|
442 |
+
elem.requestFullscreen();
|
443 |
+
}} else if (elem.mozRequestFullScreen) {{
|
444 |
+
elem.mozRequestFullScreen();
|
445 |
+
}} else if (elem.webkitRequestFullscreen) {{
|
446 |
+
elem.webkitRequestFullscreen();
|
447 |
+
}} else if (elem.msRequestFullscreen) {{
|
448 |
+
elem.msRequestFullscreen();
|
449 |
+
}}
|
450 |
+
}}, 1000);
|
451 |
+
|
452 |
+
// ์ ๋๋ฉ์ด์
์ ์ฉ (window ๊ฐ์ฒด์์ ํจ์ ํธ์ถ)
|
453 |
+
setTimeout(function() {{
|
454 |
+
if (typeof window.applyBackgroundAnimation === 'function') {{
|
455 |
+
window.applyBackgroundAnimation('animate-{st.session_state.animation_type}');
|
456 |
+
}}
|
457 |
+
}}, 1500);
|
458 |
+
</script>
|
459 |
+
"""
|
460 |
+
|
461 |
+
# HTML ์ง์ ์ฝ์
|
462 |
+
st.markdown(background_html, unsafe_allow_html=True)
|
463 |
+
|
464 |
+
# Streamlit ์์ ์จ๊ธฐ๊ธฐ
|
465 |
+
st.markdown("""
|
466 |
+
<style>
|
467 |
+
#MainMenu {visibility: hidden;}
|
468 |
+
header {visibility: hidden;}
|
469 |
+
footer {visibility: hidden;}
|
470 |
+
</style>
|
471 |
+
""", unsafe_allow_html=True)
|
472 |
+
|
473 |
+
|
474 |
+
else:
|
475 |
+
st.info("ํ์ํ ์ด๋ฏธ์ง๊ฐ ์์ต๋๋ค. ์ด๋ฏธ์ง๋ฅผ ์ถ๊ฐํด์ฃผ์ธ์.")
|
476 |
+
if st.button("๋ฏธ๋ฆฌ๋ณด๊ธฐ ์ข
๋ฃ"):
|
477 |
+
st.session_state.preview_mode = False
|
478 |
+
st.rerun()
|
479 |
+
|
480 |
+
else:
|
481 |
+
# ์ผ๋ฐ ๋ชจ๋ - ์ผ๋ฐ ๊ด๋ฆฌ ํ๋ฉด
|
482 |
+
st.title("๋์คํ๋ ์ด ์ปจํ
์ธ ๊ด๋ฆฌ")
|
483 |
+
|
484 |
+
if not st.session_state.contents:
|
485 |
+
st.info("์ฌ์ด๋๋ฐ์์ ์ด๋ฏธ์ง๋ฅผ ์ถ๊ฐํ์ธ์.")
|
486 |
+
else:
|
487 |
+
st.write("์ฌ์ด๋๋ฐ์์ ์ด๋ฏธ์ง๋ฅผ ๊ด๋ฆฌํ๊ณ ์๋ ๋ฒํผ์ ํด๋ฆญํ์ฌ ์ ์ฒดํ๋ฉด ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ์์ํ์ธ์.")
|
488 |
+
|
489 |
+
# ์ด๋ฏธ์ง ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๊ทธ๋ฆฌ๋
|
490 |
+
cols = st.columns(4)
|
491 |
+
for i, img_path in enumerate(st.session_state.contents):
|
492 |
+
if i < len(cols):
|
493 |
+
cols[i].image(img_path, caption=os.path.basename(img_path), width=200)
|
494 |
+
else:
|
495 |
+
break
|
496 |
+
|