objektify3 / interface.py
tripleS-Dev
Making expert tab
d538b9e
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'])