| | import base64 |
| | import gradio as gr |
| | import requests |
| | from typing import List, Dict, Any, Tuple |
| |
|
| | from annotator.openpose import decode_json_as_poses, draw_poses |
| | from scripts.controlnet_ui.modal import ModalInterface |
| | from modules import shared |
| |
|
| |
|
| | def parse_data_url(data_url: str): |
| | |
| | media_type, data = data_url.split(",", 1) |
| |
|
| | |
| | assert ";base64" in media_type |
| |
|
| | |
| | return base64.b64decode(data) |
| |
|
| |
|
| | def encode_data_url(json_string: str) -> str: |
| | base64_encoded_json = base64.b64encode(json_string.encode("utf-8")).decode("utf-8") |
| | return f"data:application/json;base64,{base64_encoded_json}" |
| |
|
| |
|
| | class OpenposeEditor(object): |
| | |
| | download_file = "pose.json" |
| | |
| | editor_url = "/openpose_editor_index" |
| |
|
| | def __init__(self) -> None: |
| | self.render_button = None |
| | self.download_link = None |
| | self.modal = None |
| | self.render() |
| |
|
| | def render(self): |
| | |
| | self.render_button = gr.Button(visible=False, elem_classes=["cnet-render-pose"]) |
| | |
| | |
| | self.pose_input = gr.Textbox(visible=False, elem_classes=["cnet-pose-json"]) |
| |
|
| | self.modal = ModalInterface( |
| | |
| | |
| | |
| | |
| | f'<iframe src="about:blank"></iframe>', |
| | open_button_text="Edit", |
| | open_button_classes=["cnet-edit-pose"], |
| | open_button_extra_attrs=f'title="Send pose to {OpenposeEditor.editor_url} for edit."', |
| | ).create_modal(visible=False) |
| | self.download_link = gr.HTML( |
| | value="", visible=False, elem_classes=["cnet-download-pose"] |
| | ) |
| |
|
| | def register_callbacks( |
| | self, generated_image: gr.Image, use_preview_as_input: gr.Checkbox |
| | ): |
| | def render_pose(pose_url: str) -> Tuple[Dict, Dict]: |
| | json_string = parse_data_url(pose_url) |
| | poses, height, weight = decode_json_as_poses( |
| | json_string, normalize_coords=True |
| | ) |
| | return ( |
| | |
| | gr.update( |
| | value=draw_poses( |
| | poses, |
| | height, |
| | weight, |
| | draw_body=True, |
| | draw_hand=True, |
| | draw_face=True, |
| | ), |
| | visible=True, |
| | ), |
| | |
| | gr.update(value=True), |
| | ) |
| |
|
| | self.render_button.click( |
| | fn=render_pose, |
| | inputs=[self.pose_input], |
| | outputs=[generated_image, use_preview_as_input], |
| | ) |
| |
|
| | def outputs(self) -> List[Any]: |
| | return [ |
| | self.download_link, |
| | self.modal, |
| | ] |
| |
|
| | def update(self, json_string: str) -> List[Dict]: |
| | """ |
| | Called when there is a new JSON pose value generated by running |
| | preprocessor. |
| | |
| | Args: |
| | json_string: The new JSON string generated by preprocessor. |
| | |
| | Returns: |
| | An gr.update event. |
| | """ |
| | hint = "Download the pose as .json file" |
| | html = f"""<a href='{encode_data_url(json_string)}' |
| | download='{OpenposeEditor.download_file}' title="{hint}"> |
| | JSON</a>""" |
| |
|
| | visible = json_string != "" |
| | return [ |
| | |
| | gr.update(value=html, visible=visible), |
| | |
| | gr.update( |
| | visible=visible |
| | and not shared.opts.data.get("controlnet_disable_openpose_edit", False) |
| | ), |
| | ] |
| |
|