183 lines
8.7 KiB
Python
183 lines
8.7 KiB
Python
import gradio as gr
|
|
|
|
from scripts.controlnet_ui.modal import ModalInterface
|
|
|
|
PHOTOPEA_LOGO = """
|
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
|
width="100%" viewBox="0 0 256 256" enable-background="new 0 0 256 256" xml:space="preserve"
|
|
style="width: 0.75rem; height 0.75rem; margin-left: 2px;"
|
|
>
|
|
<path fill="#18A497" opacity="1.000000" stroke="none"
|
|
d="
|
|
M1.000000,228.000000
|
|
C1.000000,162.312439 1.000000,96.624878 1.331771,30.719650
|
|
C2.026278,30.171114 2.594676,29.904894 2.721949,29.500008
|
|
C6.913495,16.165672 15.629609,7.322631 28.880219,2.875538
|
|
C29.404272,2.699659 29.633436,1.645129 30.000000,1.000000
|
|
C95.687561,1.000000 161.375122,1.000000 227.258057,1.317018
|
|
C227.660217,1.893988 227.815079,2.296565 228.081207,2.393433
|
|
C241.304657,7.206383 250.980164,15.550970 255.215851,29.410040
|
|
C255.321625,29.756128 256.383850,29.809898 257.000000,30.000000
|
|
C257.000000,95.687561 257.000000,161.375122 256.682983,227.257858
|
|
C256.106049,227.659790 255.699371,227.815521 255.607178,228.080658
|
|
C250.953033,241.462830 242.292618,250.822968 228.591782,255.214935
|
|
C228.239929,255.327698 228.190491,256.383820 228.000000,257.000000
|
|
C175.312439,257.000000 122.624878,257.000000 69.468582,256.531342
|
|
C68.672188,244.948196 68.218323,233.835587 68.052299,222.718674
|
|
C67.885620,211.557587 67.886772,200.390717 68.027298,189.229050
|
|
C68.255180,171.129044 68.084618,152.997421 69.151917,134.942368
|
|
C70.148468,118.083969 77.974228,103.689308 89.758743,91.961365
|
|
C104.435837,77.354736 122.313736,69.841736 143.417328,69.901505
|
|
C168.662338,69.972984 186.981964,90.486633 187.961487,114.156334
|
|
C189.042435,140.277435 166.783981,163.607941 140.303482,160.823074
|
|
C137.092346,160.485382 133.490692,158.365784 131.192612,155.987366
|
|
C126.434669,151.063141 126.975357,144.720825 129.168777,138.834930
|
|
C131.533630,132.489014 137.260605,130.548050 143.413757,130.046677
|
|
C150.288467,129.486496 156.424942,123.757378 157.035324,117.320816
|
|
C157.953949,107.633820 150.959381,101.769096 145.533951,101.194389
|
|
C132.238846,99.786079 120.699944,104.963120 111.676735,114.167313
|
|
C102.105782,123.930222 97.469498,136.194061 99.003151,150.234955
|
|
C100.540352,164.308228 107.108505,175.507980 118.864334,183.311539
|
|
C128.454544,189.677597 138.866959,191.786957 150.657837,190.245651
|
|
C166.242554,188.208420 179.874283,182.443329 191.251801,172.056793
|
|
C209.355011,155.530380 217.848694,134.938721 216.116119,110.085892
|
|
C214.834335,91.699440 207.721039,76.015915 195.289444,62.978828
|
|
C175.658447,42.391735 150.833389,37.257801 123.833740,42.281937
|
|
C98.675804,46.963364 78.315033,60.084667 62.208153,80.157814
|
|
C46.645889,99.552216 39.305275,121.796379 39.149052,146.201981
|
|
C38.912663,183.131317 39.666767,220.067017 40.000000,257.000000
|
|
C36.969406,257.000000 33.938812,257.000000 30.705070,256.668213
|
|
C30.298622,256.078369 30.144913,255.669220 29.884926,255.583878
|
|
C16.317770,251.131058 7.127485,242.317780 2.778462,228.591797
|
|
C2.667588,228.241821 1.613958,228.190567 1.000000,228.000000
|
|
z"/>
|
|
<path fill="#000000" opacity="1.000000" stroke="none"
|
|
d="
|
|
M40.468658,257.000000
|
|
C39.666767,220.067017 38.912663,183.131317 39.149052,146.201981
|
|
C39.305275,121.796379 46.645889,99.552216 62.208153,80.157814
|
|
C78.315033,60.084667 98.675804,46.963364 123.833740,42.281937
|
|
C150.833389,37.257801 175.658447,42.391735 195.289444,62.978828
|
|
C207.721039,76.015915 214.834335,91.699440 216.116119,110.085892
|
|
C217.848694,134.938721 209.355011,155.530380 191.251801,172.056793
|
|
C179.874283,182.443329 166.242554,188.208420 150.657837,190.245651
|
|
C138.866959,191.786957 128.454544,189.677597 118.864334,183.311539
|
|
C107.108505,175.507980 100.540352,164.308228 99.003151,150.234955
|
|
C97.469498,136.194061 102.105782,123.930222 111.676735,114.167313
|
|
C120.699944,104.963120 132.238846,99.786079 145.533951,101.194389
|
|
C150.959381,101.769096 157.953949,107.633820 157.035324,117.320816
|
|
C156.424942,123.757378 150.288467,129.486496 143.413757,130.046677
|
|
C137.260605,130.548050 131.533630,132.489014 129.168777,138.834930
|
|
C126.975357,144.720825 126.434669,151.063141 131.192612,155.987366
|
|
C133.490692,158.365784 137.092346,160.485382 140.303482,160.823074
|
|
C166.783981,163.607941 189.042435,140.277435 187.961487,114.156334
|
|
C186.981964,90.486633 168.662338,69.972984 143.417328,69.901505
|
|
C122.313736,69.841736 104.435837,77.354736 89.758743,91.961365
|
|
C77.974228,103.689308 70.148468,118.083969 69.151917,134.942368
|
|
C68.084618,152.997421 68.255180,171.129044 68.027298,189.229050
|
|
C67.886772,200.390717 67.885620,211.557587 68.052299,222.718674
|
|
C68.218323,233.835587 68.672188,244.948196 68.999924,256.531342
|
|
C59.645771,257.000000 50.291542,257.000000 40.468658,257.000000
|
|
z"/>
|
|
<path fill="#000000" opacity="1.000000" stroke="none"
|
|
d="
|
|
M257.000000,29.531342
|
|
C256.383850,29.809898 255.321625,29.756128 255.215851,29.410040
|
|
C250.980164,15.550970 241.304657,7.206383 228.081207,2.393433
|
|
C227.815079,2.296565 227.660217,1.893988 227.726715,1.317018
|
|
C237.593155,1.000000 247.186295,1.000000 257.000000,1.000000
|
|
C257.000000,10.353075 257.000000,19.707878 257.000000,29.531342
|
|
z"/>
|
|
<path fill="#000000" opacity="1.000000" stroke="none"
|
|
d="
|
|
M228.468658,257.000000
|
|
C228.190491,256.383820 228.239929,255.327698 228.591782,255.214935
|
|
C242.292618,250.822968 250.953033,241.462830 255.607178,228.080658
|
|
C255.699371,227.815521 256.106049,227.659790 256.682983,227.726517
|
|
C257.000000,237.593155 257.000000,247.186295 257.000000,257.000000
|
|
C247.646927,257.000000 238.292114,257.000000 228.468658,257.000000
|
|
z"/>
|
|
<path fill="#000000" opacity="1.000000" stroke="none"
|
|
d="
|
|
M1.000000,228.468658
|
|
C1.613958,228.190567 2.667588,228.241821 2.778462,228.591797
|
|
C7.127485,242.317780 16.317770,251.131058 29.884926,255.583878
|
|
C30.144913,255.669220 30.298622,256.078369 30.250959,256.668213
|
|
C20.406853,257.000000 10.813705,257.000000 1.000000,257.000000
|
|
C1.000000,247.646927 1.000000,238.292114 1.000000,228.468658
|
|
z"/>
|
|
<path fill="#000000" opacity="1.000000" stroke="none"
|
|
d="
|
|
M29.531342,1.000000
|
|
C29.633436,1.645129 29.404272,2.699659 28.880219,2.875538
|
|
C15.629609,7.322631 6.913495,16.165672 2.721949,29.500008
|
|
C2.594676,29.904894 2.026278,30.171114 1.331771,30.250992
|
|
C1.000000,20.406855 1.000000,10.813709 1.000000,1.000000
|
|
C10.353074,1.000000 19.707878,1.000000 29.531342,1.000000
|
|
z"/>
|
|
</svg>"""
|
|
|
|
|
|
class Photopea(object):
|
|
def __init__(self) -> None:
|
|
self.modal = None
|
|
self.triggers = []
|
|
self.render_editor()
|
|
|
|
def render_editor(self):
|
|
"""Render the editor modal."""
|
|
with gr.Group(elem_classes=["cnet-photopea-edit"]):
|
|
self.modal = ModalInterface(
|
|
# Use about:blank here as placeholder so that the iframe does not
|
|
# immediately navigate. Only navigate when the user first click
|
|
# 'Edit'. The navigation logic is in `photopea.js`.
|
|
"""
|
|
<div class="photopea-button-group">
|
|
<button class="photopea-button photopea-fetch">Fetch from ControlNet</button>
|
|
<button class="photopea-button photopea-send">Send to ControlNet</button>
|
|
</div>
|
|
<iframe class="photopea-iframe" src="about:blank"></iframe>
|
|
""",
|
|
open_button_text="Edit",
|
|
open_button_classes=["cnet-photopea-main-trigger"],
|
|
open_button_extra_attrs="hidden",
|
|
).create_modal(visible=True)
|
|
|
|
def render_child_trigger(self):
|
|
self.triggers.append(
|
|
gr.HTML(
|
|
f"""<div class="cnet-photopea-child-trigger">
|
|
Edit {PHOTOPEA_LOGO}
|
|
</div>"""
|
|
)
|
|
)
|
|
|
|
def attach_photopea_output(self, generated_image: gr.Image):
|
|
"""Called in ControlNetUiGroup to attach preprocessor preview image Gradio element
|
|
as the photopea output. If the front-end directly change the img HTML element's src
|
|
to reflect the edited image result from photopea, the backend won't be notified.
|
|
|
|
In this method we let the front-end upload the result image an invisible gr.Image
|
|
instance and mirrors the value to preprocessor preview gr.Image. This is because
|
|
the generated image gr.Image instance is inferred to be an output image by Gradio
|
|
and has no ability to accept image upload directly.
|
|
|
|
Arguments:
|
|
generated_image: preprocessor result Gradio Image output element.
|
|
|
|
Returns:
|
|
None
|
|
"""
|
|
output = gr.Image(
|
|
visible=False,
|
|
source="upload",
|
|
type="numpy",
|
|
elem_classes=["cnet-photopea-output"],
|
|
)
|
|
|
|
output.upload(
|
|
fn=lambda img: img,
|
|
inputs=[output],
|
|
outputs=[generated_image],
|
|
)
|