File size: 8,942 Bytes
c19ca42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
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],
        )