Spaces:
Runtime error
Runtime error
import random as rn | |
import gradio as gr | |
from PIL import Image | |
import pillow_avif | |
import backend | |
from backend import season_color | |
mh_season = ['Atom01', 'Binary01', 'Cream01', 'Divine01', 'Ever01'] | |
mh_season_default = 'Ever01' | |
mh_class = ['Welcome', 'First', 'Special', 'Premier', 'OMA1', 'OMA2'] | |
mh_member_names = [ | |
"SeoYeon", "HyeRin", "JiWoo", "ChaeYeon", "YooYeon", "SooMin", | |
"Nakyoung", "YuBin", "Kaede", "DaHyun", "Kotone", "YeonJi", | |
"Nien", "SoHyun", "Xinyu", "Mayu", "Lynn", "JooBin", | |
"HaYeon", "ShiOn", "ChaeWon", "Sullin", "SeoAh", "JiYeon", | |
'HeeJin', 'HaSeul', 'KimLip', 'JinSoul', 'Choerry' | |
] | |
mh_artist_names = ['tripleS', 'ARTMS'] | |
mh_number = [ | |
100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, | |
201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, | |
301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, | |
321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, | |
341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, | |
401 | |
] | |
mh_line = ['Z', 'A'] | |
def x_y(x): | |
return x | |
def quick_tab_selected(*all_components): | |
image, path = backend.front('quick', all_components[0], *all_components[1:]) #마지막 all_components는 list가 아니여야함 | |
return 'quick', image, path | |
def balanced_tab_selected(*all_components): | |
image, path = backend.front('balanced', all_components[0], *all_components[1:]) #마지막 all_components는 list가 아니여야함 | |
return 'balanced', image, path | |
def expert_tab_selected(*all_components): | |
image, path = backend.front('expert', all_components[0], *all_components[1:]) #마지막 all_components는 list가 아니여야함 | |
return 'expert', image, path | |
def class_change(class_name, number, line): | |
visible = False | |
match class_name: | |
case 'First': | |
visible = True | |
number = rn.randint(101,120) | |
case 'Welcome': | |
number = 100 | |
case 'Special': | |
number = rn.randint(201, 221) | |
case 'Double': | |
visible = True | |
number = rn.randint(301, 258) | |
case 'Premier': | |
number = '401' | |
line = 'A' | |
case 'OMA1': | |
number = '304' | |
case 'OMA2': | |
number = '322' | |
return gr.Radio(visible=visible), number, line | |
def expert_color_change(radio): | |
visible = [False, False, False] | |
if radio == 'Static': | |
visible[0] = True | |
elif radio == 'Gradient': | |
visible[1] = True | |
elif radio == 'Image': | |
visible[2] = True | |
return gr.ColorPicker(visible=visible[0]), gr.Slider(visible=visible[1]), gr.Image(visible=visible[2]) | |
# replaced it in backend.image_uploaded | |
""" | |
def resize_image(image): | |
if not isinstance(image, Image.Image): | |
raise gr.Error("This format cannot be uploaded.") | |
if not image.size == (1083, 1673): | |
target_width, target_height = (1083, 1673) | |
# 원본 이미지의 너비와 높이 | |
original_width, original_height = image.size | |
# 원하는 비율 계산 | |
target_ratio = target_width / target_height | |
original_ratio = original_width / original_height | |
if original_ratio > target_ratio: | |
# 이미지가 가로로 더 길 경우: 양쪽을 잘라냄 | |
new_width = int(original_height * target_ratio) | |
new_height = original_height | |
left = (original_width - new_width) // 2 | |
top = 0 | |
right = left + new_width | |
bottom = new_height | |
else: | |
# 이미지가 세로로 더 길 경우: 위아래를 잘라냄 | |
new_width = original_width | |
new_height = int(original_width / target_ratio) | |
left = 0 | |
top = (original_height - new_height) // 2 | |
right = new_width | |
bottom = top + new_height | |
img_cropped = image.crop((left, top, right, bottom)) | |
img_resized = img_cropped.resize((target_width, target_height), Image.Resampling.LANCZOS) | |
return img_resized, img_resized | |
else: | |
return image, image | |
""" | |
# Updated CSS with 'top: 0;' and overflow adjustments | |
css = """ | |
body, html, .gradio-container, .gradio-container > .gr-block { | |
overflow: visible !important; | |
-webkit-touch-callout:none; | |
-webkit-user-select:none; | |
-webkit-tap-highlight-color:rgba(0, 0, 0, 0); | |
} | |
.sticky-image { | |
position: sticky; | |
top: 10px; | |
height: 45dvh; | |
z-index: 1000; | |
} | |
/* When dvh < dvw, set height to 80dvh */ | |
@media (min-aspect-ratio: 1.3/1) { | |
.sticky-image { | |
height: 80dvh; | |
} | |
} | |
footer{display:none !important} | |
""" | |
animation = """ | |
function createGradioAnimation() { | |
var container = document.createElement('div'); | |
container.id = 'gradio-animation'; | |
container.style.fontSize = '2em'; | |
container.style.fontWeight = 'bold'; | |
container.style.textAlign = 'center'; | |
container.style.marginTop = '0px'; | |
container.style.marginBottom = '5px'; | |
var text = 'Objektify'; | |
for (var i = 0; i < text.length; i++) { | |
(function(i){ | |
setTimeout(function(){ | |
var letter = document.createElement('span'); | |
letter.style.opacity = '0'; | |
letter.style.transition = 'opacity 0.5s'; | |
letter.innerText = text[i]; | |
container.appendChild(letter); | |
setTimeout(function() { | |
letter.style.opacity = '1'; | |
}, 50); | |
}, i * 250); | |
})(i); | |
} | |
var gradioContainer = document.querySelector('.gradio-container'); | |
gradioContainer.insertBefore(container, gradioContainer.firstChild); | |
setTimeout(function() { | |
container.style.transition = 'all 2s'; | |
container.style.fontSize = '1em'; | |
container.style.letterSpacing = '0.1em'; | |
}, 3000); | |
return 'Animation created'; | |
} | |
""" | |
theme = gr.themes.Ocean( | |
primary_hue="violet", | |
neutral_hue="zinc", | |
) | |
with gr.Blocks(css=css, theme=theme, js=animation) as objektify: | |
with gr.Group(visible=False): | |
current_tab = gr.Textbox('quick', label='mode') | |
original_image = gr.Image(type='pil', format='png', image_mode='RGBA') | |
with gr.Tab('Front'): | |
with gr.Row(): | |
with gr.Row(elem_classes='sticky-image'): | |
input_image = gr.Image(type='filepath', interactive=True, show_download_button=True, show_fullscreen_button=True, format='png', show_label=False, elem_classes='sticky-image', sources='upload') | |
with gr.Column(): | |
with gr.Row(): | |
common_name = gr.Dropdown(label='Name',choices=mh_member_names, allow_custom_value=True, interactive=True) | |
common_group = gr.Dropdown(label='Group', choices=mh_artist_names, allow_custom_value=True, interactive=True) | |
with gr.Tab('Quick') as quick: | |
quick_season = gr.Radio(label='Season', value=mh_season_default,choices=mh_season) | |
with gr.Tab('Balanced') as balanced: | |
balanced_class = gr.Radio(label='Class', value='Welcome',choices=mh_class) | |
balanced_season = gr.Radio(label='Season', value=mh_season_default, choices=mh_season, visible=False) | |
with gr.Row(): | |
balanced_number = gr.Dropdown(label='Number', choices=mh_number, allow_custom_value=True) | |
balanced_line = gr.Dropdown(label='On/Offline', choices=mh_line, allow_custom_value=True) | |
balanced_serial = gr.Textbox(label='Serial', value='1', interactive=True) | |
with gr.Tab('Expert') as expert: | |
with gr.Column(): | |
expert_color_radio = gr.Radio(label='Main Color', choices=['Static', 'Gradient', 'Image'], value='Static') | |
with gr.Row(): | |
with gr.Group(): | |
expert_static = gr.ColorPicker(interactive=True, visible=True, value=season_color[mh_season_default], label='Main Color') | |
expert_gradient = gr.Slider(interactive=True, visible=False, minimum=1, maximum=1000) | |
expert_image = gr.Image(interactive=True, visible=False) | |
expert_text_color = gr.ColorPicker(interactive=True, visible=True, value='#000000', label='Text Color') | |
with gr.Row(): | |
expert_number = gr.Dropdown(label='Number', choices=mh_number, allow_custom_value=True) | |
expert_line = gr.Dropdown(label='On/Offline', choices=mh_line, allow_custom_value=True) | |
expert_serial = gr.Textbox(label='Serial', value='1', interactive=True) | |
with gr.Row(): | |
download_button = gr.DownloadButton(variant="primary") | |
share_button = gr.Button('Share') | |
input_image.upload(fn=backend.image_uploaded, inputs=input_image, outputs=[original_image]) | |
input_image.clear(fn=lambda : gr.Image(value=None), outputs=original_image) | |
#quick_season.select(fn=x_y, inputs=quick_season, outputs=balanced_season) | |
#balanced_season.select(fn=x_y, inputs=balanced_season, outputs=quick_season) | |
balanced_class.change(fn=class_change, inputs=[balanced_class, balanced_number, balanced_line], outputs=[balanced_season, balanced_number, balanced_line]) | |
expert_color_radio.change(fn=expert_color_change, inputs=expert_color_radio, outputs=[expert_static, expert_gradient, expert_image]) | |
all_components = [original_image, common_name, common_group, quick_season, balanced_season, balanced_class, balanced_number, balanced_line, balanced_serial, expert_color_radio, expert_static, expert_gradient, expert_image, expert_text_color, expert_number, expert_line, expert_serial] | |
quick.select(fn=quick_tab_selected, outputs=[current_tab, input_image, download_button], inputs=[]+all_components) | |
balanced.select(fn=balanced_tab_selected, outputs=[current_tab, input_image, download_button], inputs=all_components) | |
expert.select(fn=expert_tab_selected, outputs=[current_tab, input_image, download_button], inputs=all_components) | |
for component in all_components: | |
if not component == balanced_class: # avoid double generate | |
component.change(fn=backend.front, inputs=[current_tab]+all_components, outputs=[input_image, download_button]) | |
#with gr.Tab('back'): | |
if __name__ == '__main__': | |
objektify.launch(server_name='0.0.0.0', allowed_paths=['./data']) |