Spaces:
Sleeping
Sleeping
| import os | |
| import gradio as gr | |
| from PIL import Image | |
| from utils.setting_names import names_mapping | |
| from utils import ( | |
| load_tiles_data, | |
| pixel_palette_image, | |
| map_tiles, | |
| overlay_preview, | |
| overlay_tiles, | |
| apply_border, | |
| create_color_grid, | |
| create_logo_text, | |
| combine_component_image, | |
| save_tiles_data, | |
| update_wall_view | |
| ) | |
| langangue = 'cn' | |
| font_name = "华文细黑.ttf" | |
| abs_path_font = os.path.abspath(__file__).split(os.sep)[:-1] | |
| font_abs_path = os.sep.join(abs_path_font) | |
| avaliable_tile_types = [ | |
| "磷光", "磷光AB", "磷光BA", | |
| "矩形", | |
| "三角尖上", "三角尖下", | |
| "圆平铺", | |
| "圆错位" | |
| ] | |
| # avaliable_tile_types_map = { | |
| # "磷光": "Hexagon", | |
| # "磷光AB": "HexagonCurved_AB", | |
| # "磷光BA": "HexagonCurved_BA", | |
| # "矩形": "Rectangle", | |
| # "三角尖上": "Triangle_TipUp", | |
| # "三角尖下": "Triangle_TipDown", | |
| # "圆平铺": "Circle_Alignment", | |
| # "圆错位": "Circle_Displacement" | |
| # } | |
| names = dict((label_name, lan[langangue]) for label_name, lan in names_mapping.items()) | |
| def get_image_examples(): | |
| examples=[ | |
| os.path.join(os.path.dirname(__file__), "images/0.png"), | |
| os.path.join(os.path.dirname(__file__), "images/1.jpg"), | |
| os.path.join(os.path.dirname(__file__), "images/2.jpg"), | |
| os.path.join(os.path.dirname(__file__), "images/3.jpg"), | |
| os.path.join(os.path.dirname(__file__), "images/4.png"), | |
| os.path.join(os.path.dirname(__file__), "images/5.png"), | |
| ] | |
| return examples | |
| with gr.Blocks() as demo: | |
| gr.Markdown(names["page_header"]) | |
| with gr.Row(equal_height=False): | |
| with gr.Column(): | |
| with gr.Accordion(open=True, label=names['raw_image']): | |
| raw_image = gr.Image(type="pil") | |
| # parameters for image color reduce | |
| with gr.Accordion(open=True, label=names["image_color_reduce_settings"]): | |
| with gr.Row(equal_height=True): | |
| max_colors = gr.Slider(minimum=1, maximum=30, step=1, value=16, label=names["max_colors"]) | |
| flip_vertical = gr.Checkbox(label=names['flip_vertical'], value=False) | |
| flip_horizontal = gr.Checkbox(label=names['flip_horizontal'], value=False) | |
| rotation_angle = gr.Number(precision=0, minimum=0, maximum=360, step=1, label=names['rotation_counter_clock_wise'], value=0) | |
| scale_ratio = gr.Slider(minimum=0.1, maximum=1, step=0.1, label=names['scale_ratio'], value=0.25, interactive=True) | |
| rgb_palette = gr.Textbox(placeholder=names["rgb_palette_place_holder"], label=names["rgb_palette"]) | |
| color_list = gr.Textbox(label=names["color_list"]) | |
| btn_reduce_colors = gr.Button(names['run_reduce_colors'], variant="primary") | |
| color_reduced_path = gr.Textbox(visible=False) | |
| color_reduced_image = gr.Image(type="pil", label=names['color_reduced_image'], interactive=False) | |
| # parameters for tile settings | |
| with gr.Accordion(open=True, label=names["wall_settings"]): | |
| with gr.Row(equal_height=True): | |
| painting_width = gr.Number(precision=None, minimum=1, maximum=99999, step=1, label=names['painting_width'], value=2400) | |
| painting_height = gr.Number(precision=None, minimum=1, maximum=99999, step=1, label=names['painting_height'], value=3500) | |
| painting_color = gr.Dropdown( | |
| ['白色', '黑色'], | |
| label=names["painting_color"], value='白色' | |
| ) | |
| with gr.Accordion(open=False, label=names["wall_mask_settings"]): | |
| with gr.Row(equal_height=True): | |
| wall_boundary_points = gr.Textbox(placeholder=names["wall_boundary_points_place_holder"], label=names["wall_boundary_points"]) | |
| wall_curve_types = gr.Textbox(placeholder=names["wall_curve_types_place_holder"], label=names["wall_curve_types"]) | |
| wall_view = gr.Image(type="pil", label=names['wall_image'], interactive=False, visible=True) | |
| btn_wall_preview = gr.Button(names['btn_wall_preview'], variant="primary") | |
| use_wall = gr.Checkbox(label=names['use_wall'], value=True) | |
| with gr.Accordion(open=True, label=names["tile_settings"]): | |
| with gr.Row(equal_height=True): | |
| tile_type = gr.Dropdown( | |
| avaliable_tile_types, | |
| label=names["tile_type"], value=avaliable_tile_types[0] | |
| ) | |
| tile_layout_vertical = gr.Checkbox(label=names['tile_layout_vertical'], value=True) | |
| efficiency_priority = gr.Checkbox(label=names['efficiency_priority'], value=True) | |
| with gr.Row(equal_height=True, visible=False) as option1_row: | |
| tile_width = gr.Slider(minimum=1.0, maximum=999, step=0.1, label=names['tile_width'], value=100, interactive=True) | |
| tile_height = gr.Slider(minimum=1.0, maximum=999, step=0.1, label=names['tile_height'], value=100, interactive=True) | |
| with gr.Row(equal_height=True, visible=True) as option2_row: | |
| tile_width_hex = gr.Slider(minimum=1.0, maximum=999, step=0.1, label=names['tile_width'], value=50, interactive=True) | |
| tile_height_middle = gr.Slider(minimum=0.0, maximum=999, step=0.1, label=names['tile_height_middle'], value=60, interactive=True) | |
| tile_height_tip = gr.Slider(minimum=1.0, maximum=999, step=0.1, label=names['tile_height_tip'], value=30, interactive=True) | |
| with gr.Row(equal_height=True, visible=False) as option3_row: | |
| tile_radius = gr.Slider(minimum=10.0, maximum=999, step=0.1, label=names['tile_radius'], value=25, interactive=True) | |
| with gr.Row(equal_height=True): | |
| x_center_start = gr.Slider(minimum=0, maximum=25, step=0.1, label=names['x_center_start'], value=0, interactive=True) | |
| y_center_start = gr.Slider(minimum=0, maximum=60, step=0.1, label=names['y_center_start'], value=0, interactive=True) | |
| with gr.Row(equal_height=True): | |
| gap_horizontal = gr.Slider(minimum=0, maximum=10, step=0.1, label=names['gap_horizontal'], value=0, interactive=True) | |
| gap_vertical = gr.Slider(minimum=0, maximum=10, step=0.1, label=names['gap_vertical'], value=0, interactive=True) | |
| def update_options_and_center(tile_type, tile_layout_vertical, tile_width, tile_height, tile_width_hex, tile_height_tip, tile_height_middle, tile_radius): | |
| option1_visibility = False | |
| option2_visibility = False | |
| option3_visibility = False | |
| if tile_type in ["矩形"]: | |
| option1_visibility = True | |
| option2_visibility = False | |
| option3_visibility = False | |
| if tile_layout_vertical: | |
| x_value = tile_width / 2 | |
| y_value = tile_height / 2 | |
| x_max = tile_width / 2 | |
| y_max = tile_height / 2 | |
| else: | |
| x_value = tile_height / 2 | |
| y_value = tile_width / 2 | |
| x_max = tile_height / 2 | |
| y_max = tile_width / 2 | |
| elif tile_type in ["三角尖上", "三角尖下"]: | |
| option1_visibility = True | |
| option2_visibility = False | |
| option3_visibility = False | |
| x_value = 0 | |
| y_value = 0 | |
| if tile_layout_vertical: | |
| x_max = tile_width / 2 | |
| y_max = tile_height / 2 | |
| else: | |
| x_max = tile_height / 2 | |
| y_max = tile_width / 2 | |
| elif tile_type in ["磷光AB", "磷光BA", "磷光"]: | |
| option1_visibility = False | |
| option2_visibility = True | |
| option3_visibility = False | |
| x_value = 0 | |
| y_value = 0 | |
| if tile_layout_vertical: | |
| x_max = tile_width_hex / 2 | |
| y_max = (2 * tile_height_tip + tile_height_middle) / 2 | |
| else: | |
| x_max = (2 * tile_height_tip + tile_height_middle) / 2 | |
| y_max = tile_width_hex / 2 | |
| elif tile_type in ["圆平铺", "圆错位"]: | |
| option1_visibility = False | |
| option2_visibility = False | |
| option3_visibility = True | |
| x_value = 0 | |
| y_value = 0 | |
| x_max = tile_radius | |
| y_max = tile_radius | |
| x_value = round(x_value, 1) | |
| y_value = round(y_value, 1) | |
| x_max = round(x_max, 1) | |
| y_max = round(y_max, 1) | |
| return [ | |
| gr.update(visible=option1_visibility), | |
| gr.update(visible=option2_visibility), | |
| gr.update(visible=option3_visibility), | |
| gr.update(value=x_value, maximum=x_max), | |
| gr.update(value=y_value, maximum=y_max), | |
| ] | |
| tile_type.change( | |
| fn=update_options_and_center, | |
| inputs=[tile_type, tile_layout_vertical, tile_width, tile_height, tile_width_hex, tile_height_tip, tile_height_middle, tile_radius], | |
| outputs=[option1_row, option2_row, option3_row, x_center_start, y_center_start] | |
| ) | |
| tile_layout_vertical.change( | |
| fn=update_options_and_center, | |
| inputs=[tile_type, tile_layout_vertical, tile_width, tile_height, tile_width_hex, tile_height_tip, tile_height_middle, tile_radius], | |
| outputs=[option1_row, option2_row, option3_row, x_center_start, y_center_start] | |
| ) | |
| tile_width.change( | |
| fn=update_options_and_center, | |
| inputs=[tile_type, tile_layout_vertical, tile_width, tile_height, tile_width_hex, tile_height_tip, tile_height_middle, tile_radius], | |
| outputs=[option1_row, option2_row, option3_row, x_center_start, y_center_start] | |
| ) | |
| tile_height.change( | |
| fn=update_options_and_center, | |
| inputs=[tile_type, tile_layout_vertical, tile_width, tile_height, tile_width_hex, tile_height_tip, tile_height_middle, tile_radius], | |
| outputs=[option1_row, option2_row, option3_row, x_center_start, y_center_start] | |
| ) | |
| tile_width_hex.change( | |
| fn=update_options_and_center, | |
| inputs=[tile_type, tile_layout_vertical, tile_width, tile_height, tile_width_hex, tile_height_tip, tile_height_middle, tile_radius], | |
| outputs=[option1_row, option2_row, option3_row, x_center_start, y_center_start] | |
| ) | |
| tile_height_tip.change( | |
| fn=update_options_and_center, | |
| inputs=[tile_type, tile_layout_vertical, tile_width, tile_height, tile_width_hex, tile_height_tip, tile_height_middle, tile_radius], | |
| outputs=[option1_row, option2_row, option3_row, x_center_start, y_center_start] | |
| ) | |
| tile_height_middle.change( | |
| fn=update_options_and_center, | |
| inputs=[tile_type, tile_layout_vertical, tile_width, tile_height, tile_width_hex, tile_height_tip, tile_height_middle, tile_radius], | |
| outputs=[option1_row, option2_row, option3_row, x_center_start, y_center_start] | |
| ) | |
| tile_radius.change( | |
| fn=update_options_and_center, | |
| inputs=[tile_type, tile_layout_vertical, tile_width, tile_height, tile_width_hex, tile_height_tip, tile_height_middle, tile_radius], | |
| outputs=[option1_row, option2_row, option3_row, x_center_start, y_center_start] | |
| ) | |
| with gr.Column(): | |
| btn_map_tiles = gr.Button(names['run_map_tiles'], variant="primary") | |
| tiled_image = gr.Image(type="pil", label=names['tiled_image'], interactive=False) | |
| temp_path_tiled_image = gr.Textbox(visible=False) | |
| temp_tiles_data_path = gr.Textbox(visible=False) | |
| with gr.Column(): | |
| with gr.Accordion(open=False, label=names["overlay"]): | |
| overlay_file = gr.File(label=names['load_overlay_data'], file_types=["json"]) | |
| def update_max_x_slider(value): | |
| return gr.Slider(minimum=-1000, maximum=value, step=1, value=0, label=names["overlay_x_start"]) | |
| def update_max_y_slider(value): | |
| return gr.Slider(minimum=-1000, maximum=value, step=1, value=0, label=names["overlay_y_start"]) | |
| overlay_global_mode = gr.Checkbox(label=names['overlay_global_mode'], value=False) | |
| overlay_keep_colors = gr.Textbox(placeholder=names["overlay_keep_colors_place_holder"], label=names["overlay_keep_colors"]) | |
| overlay_x_start = gr.Slider(minimum=-1000, maximum=99999, step=1, value=0, label=names["overlay_x_start"]) | |
| overlay_y_start = gr.Slider(minimum=-1000, maximum=99999, step=1, value=0, label=names["overlay_y_start"]) | |
| painting_width.change(fn=update_max_x_slider, inputs=painting_width, outputs=overlay_x_start) | |
| painting_height.change(fn=update_max_y_slider, inputs=painting_height, outputs=overlay_y_start) | |
| btn_overlay_preview = gr.Button(names['btn_overlay_preview'], variant="primary") | |
| overlay_img = gr.Image(type="pil", label=names['overlay_img'], interactive=False) | |
| btn_create_overlay = gr.Button(names['btn_create_overlay'], variant="primary") | |
| with gr.Column(): | |
| gr.Examples( | |
| examples=get_image_examples(), | |
| inputs=[raw_image], | |
| fn=None, | |
| outputs=[raw_image], | |
| cache_examples=False, | |
| label=names['examples'] | |
| ) | |
| with gr.Column(): | |
| with gr.Accordion(open=True, label=names['label_image']): | |
| label_image = gr.Image(type="pil", label=names['label_image'], interactive=False) | |
| with gr.Row(equal_height=True): | |
| temp_path_label_image = gr.Textbox(visible=False) | |
| def adjust_font_size(painting_width, painting_height): | |
| # You can define your logic here to adjust the font size based on painting dimensions | |
| # For example, a simple proportional adjustment might be: | |
| base_width = 2400 | |
| base_height = 3500 | |
| base_font_size = 50 | |
| width_ratio = painting_width / base_width | |
| height_ratio = painting_height / base_height | |
| new_font_size = int(base_font_size * min(width_ratio, height_ratio)) | |
| return new_font_size | |
| label_font_size = gr.Number(precision=0, minimum=1, maximum=500, step=1, label=names['label_font_size'], value=50) | |
| painting_width.change( | |
| fn=adjust_font_size, | |
| inputs=[painting_width, painting_height], | |
| outputs=[label_font_size] | |
| ) | |
| painting_height.change( | |
| fn=adjust_font_size, | |
| inputs=[painting_width, painting_height], | |
| outputs=[label_font_size] | |
| ) | |
| btn_label = gr.Button(names['create_label'], variant="primary") | |
| with gr.Accordion(open=True, label=names['logo_image']): | |
| logo_image = gr.Image(type="pil", label=names['logo_image'], interactive=False) | |
| temp_path_logo_image = gr.Textbox(visible=False) | |
| btn_logo = gr.Button(names['create_logo'], variant="primary") | |
| with gr.Accordion(open=True, label=names['grid_image']): | |
| grid_image = gr.Image(type="pil", label=names['grid_image'], interactive=False) | |
| temp_path_grid_image = gr.Textbox(visible=False) | |
| btn_grid = gr.Button(names['create_grid'], variant="primary") | |
| with gr.Accordion(open=True, label=names['final_image']): | |
| final_image = gr.Image(type="pil", label=names['final_image'], interactive=False) | |
| temp_path_final_image = gr.Textbox(visible=False) | |
| btn_final_image = gr.Button(names['create_final_image'], variant="primary") | |
| save_button = gr.Button("保存文件") | |
| save_text = gr.Textbox() | |
| with gr.Accordion(open=False, label=names['load_tiles_data']): | |
| tile_file = gr.File(label=names['load_tiles_data'], file_types=["json"]) | |
| rebuild_color_reduced_img = gr.Checkbox(label=names['rebuild_color_reduced_img'], value=False) | |
| tile_file.change(fn=load_tiles_data, inputs=[tile_file, rebuild_color_reduced_img], outputs=[ | |
| max_colors, | |
| color_list, | |
| rgb_palette, | |
| color_reduced_image, | |
| color_reduced_path, | |
| painting_width, | |
| painting_height, | |
| painting_color, | |
| wall_boundary_points, | |
| wall_curve_types, | |
| tile_type, | |
| tile_layout_vertical, | |
| tile_width, | |
| tile_height, | |
| tile_width_hex, | |
| tile_height_tip, | |
| tile_height_middle, | |
| tile_radius, | |
| x_center_start, | |
| y_center_start, | |
| gap_horizontal, | |
| gap_vertical, | |
| tiled_image, | |
| temp_path_tiled_image, | |
| temp_tiles_data_path | |
| ]) | |
| def load_temp_image(temp_path): | |
| if isinstance(temp_path, str): | |
| return Image.open(temp_path) | |
| else: | |
| raise ValueError(f"Expected a string path, got {type(temp_path)}") | |
| btn_reduce_colors.click( | |
| fn=pixel_palette_image, | |
| inputs=[ | |
| raw_image, | |
| rgb_palette, | |
| max_colors, | |
| flip_vertical, | |
| flip_horizontal, | |
| rotation_angle, | |
| scale_ratio | |
| ], | |
| outputs=[color_reduced_path, color_list] | |
| ).then( | |
| fn=load_temp_image, | |
| inputs=[color_reduced_path], | |
| outputs=color_reduced_image | |
| ) | |
| btn_wall_preview.click( | |
| fn=update_wall_view, | |
| inputs=[ | |
| painting_width, | |
| painting_height, | |
| wall_boundary_points, | |
| wall_curve_types | |
| ], | |
| outputs=wall_view | |
| ) | |
| btn_map_tiles.click( | |
| fn=map_tiles, | |
| inputs=[ | |
| color_list, | |
| color_reduced_path, | |
| painting_width, | |
| painting_height, | |
| painting_color, | |
| wall_boundary_points, | |
| wall_curve_types, | |
| use_wall, | |
| tile_type, | |
| tile_layout_vertical, | |
| efficiency_priority, | |
| tile_width, | |
| tile_height, | |
| tile_width_hex, | |
| tile_height_tip, | |
| tile_height_middle, | |
| tile_radius, | |
| x_center_start, | |
| y_center_start, | |
| gap_horizontal, | |
| gap_vertical | |
| ], | |
| outputs=[tiled_image, temp_path_tiled_image, temp_tiles_data_path] | |
| ) | |
| btn_overlay_preview.click( | |
| fn=overlay_preview, | |
| inputs=[ | |
| overlay_file, overlay_keep_colors | |
| ], | |
| outputs=[overlay_keep_colors, overlay_img] | |
| ) | |
| btn_create_overlay.click( | |
| fn=overlay_tiles, | |
| inputs=[ | |
| temp_tiles_data_path, overlay_file, overlay_x_start, overlay_y_start, overlay_global_mode, overlay_keep_colors, painting_color | |
| ], | |
| outputs=[color_list, tiled_image, temp_path_tiled_image, temp_tiles_data_path] | |
| ) | |
| btn_label.click( | |
| fn=apply_border, | |
| inputs=[ | |
| temp_tiles_data_path, | |
| label_font_size, | |
| painting_color, | |
| ], | |
| outputs=[label_image, temp_path_label_image] | |
| ) | |
| btn_logo.click( | |
| fn=create_logo_text, | |
| inputs=[ | |
| painting_width, | |
| painting_height | |
| ], | |
| outputs=[logo_image, temp_path_logo_image] | |
| ) | |
| btn_grid.click( | |
| fn=create_color_grid, | |
| inputs=[ | |
| painting_width, | |
| painting_height, | |
| tile_width, | |
| tile_height, | |
| tile_width_hex, | |
| tile_height_tip, | |
| tile_height_middle, | |
| tile_radius, | |
| color_list, | |
| tile_type | |
| ], | |
| outputs=[grid_image, temp_path_grid_image] | |
| ) | |
| btn_final_image.click( | |
| fn=combine_component_image, | |
| inputs=[ | |
| painting_width, | |
| painting_height, | |
| temp_path_label_image, | |
| temp_path_logo_image, | |
| temp_path_grid_image | |
| ], | |
| outputs=[final_image, temp_path_final_image] | |
| ) | |
| save_button.click( | |
| fn=save_tiles_data, | |
| inputs=[temp_path_label_image, temp_path_logo_image, temp_path_final_image, temp_tiles_data_path], | |
| outputs=save_text) | |
| demo.launch(share=False, debug=False) | |