ssboost commited on
Commit
c6538dc
ยท
verified ยท
1 Parent(s): ae247dd

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +246 -1
app.py CHANGED
@@ -1,2 +1,247 @@
1
  import os
2
- exec(os.environ.get('APP'))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import os
2
+ import logging
3
+ import replicate
4
+ import gradio as gr
5
+ from PIL import Image
6
+ import tempfile
7
+ import uuid
8
+
9
+ # ๋กœ๊น… ์„ค์ •
10
+ logger = logging.getLogger(__name__)
11
+
12
+ # ํ™˜๊ฒฝ๋ณ€์ˆ˜์—์„œ ์„ค์ •๊ฐ’๋“ค ๊ฐ€์ ธ์˜ค๊ธฐ
13
+ REPLICATE_API_TOKEN = os.environ.get("REPLICATE_API_TOKEN", "")
14
+ APP_PASSWORD = os.environ.get("APP_PASSWORD", "")
15
+ CLARITY_MODEL = os.environ.get("CLARITY_MODEL", "")
16
+
17
+ # ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๊ฒ€์ฆ
18
+ if not REPLICATE_API_TOKEN:
19
+ logger.warning("REPLICATE_API_TOKEN์ด ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ด์ฃผ์„ธ์š”.")
20
+
21
+ if not APP_PASSWORD:
22
+ logger.warning("APP_PASSWORD๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ด์ฃผ์„ธ์š”.")
23
+
24
+ if not CLARITY_MODEL:
25
+ logger.warning("CLARITY_MODEL์ด ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•ด์ฃผ์„ธ์š”.")
26
+
27
+ # ์ž„์‹œ ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ
28
+ TEMP_DIR = os.path.join(tempfile.gettempdir(), "image_processor")
29
+ os.makedirs(TEMP_DIR, exist_ok=True)
30
+ logger.info(f"์ž„์‹œ ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ: {TEMP_DIR}")
31
+
32
+ def upscale_image(
33
+ image,
34
+ scale_factor=2,
35
+ output_format="jpg",
36
+ sd_model="juggernaut_reborn.safetensors [338b85bc4f]",
37
+ resemblance=0.6,
38
+ creativity=0.35,
39
+ prompt="masterpiece, best quality, highres, <lora:more_details:0.5> <lora:SDXLrender_v2.0:1>",
40
+ negative_prompt="(worst quality, low quality, normal quality:2) JuggernautNegative-neg",
41
+ seed=1337,
42
+ dynamic=6,
43
+ sharpen=0
44
+ ):
45
+ """
46
+ Clarity Upscaler๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฏธ์ง€ ํ™”์งˆ์„ ๊ฐœ์„ ํ•ฉ๋‹ˆ๋‹ค.
47
+
48
+ Args:
49
+ image: ์ž…๋ ฅ ์ด๋ฏธ์ง€
50
+ scale_factor: ํ™•๋Œ€ ๋น„์œจ (๊ธฐ๋ณธ๊ฐ’: 2)
51
+ output_format: ์ถœ๋ ฅ ํ˜•์‹ (๊ธฐ๋ณธ๊ฐ’: jpg)
52
+ sd_model: ์‚ฌ์šฉํ•  SD ๋ชจ๋ธ
53
+ resemblance: ์›๋ณธ๊ณผ์˜ ์œ ์‚ฌ๋„ (0.0-1.0)
54
+ creativity: ์ฐฝ์˜์„ฑ ์ˆ˜์ค€ (0.0-1.0)
55
+ prompt: ์—…์Šค์ผ€์ผ๋ง ๊ฐ€์ด๋“œ ํ”„๋กฌํ”„ํŠธ
56
+ negative_prompt: ๋„ค๊ฑฐํ‹ฐ๋ธŒ ํ”„๋กฌํ”„ํŠธ
57
+ seed: ๋žœ๋ค ์‹œ๋“œ
58
+ dynamic: ๋‹ค์ด๋‚˜๋ฏน ์ž„๊ณ„๊ฐ’ (1-10)
59
+ sharpen: ์„ ๋ช…๋„ (0-2)
60
+
61
+ Returns:
62
+ ๊ฐœ์„ ๋œ ์ด๋ฏธ์ง€
63
+ """
64
+ if not REPLICATE_API_TOKEN:
65
+ raise ValueError("REPLICATE_API_TOKEN์ด ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.")
66
+
67
+ if not CLARITY_MODEL:
68
+ raise ValueError("CLARITY_MODEL์ด ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.")
69
+
70
+ try:
71
+ # ์ด๋ฏธ์ง€ ์ €์žฅ
72
+ temp_input_path = os.path.join(TEMP_DIR, f"input_{uuid.uuid4()}.png")
73
+ image.save(temp_input_path)
74
+ logger.info(f"์ž…๋ ฅ ์ด๋ฏธ์ง€ ์ €์žฅ: {temp_input_path}")
75
+
76
+ # Replicate ์„ค์ •
77
+ replicate.client.Client(api_token=REPLICATE_API_TOKEN)
78
+
79
+ # ๋กœ๊ทธ ์ •๋ณด ์ถœ๋ ฅ
80
+ logger.info("=== Clarity Upscaler ์‹คํ–‰ ์ •๋ณด ===")
81
+ logger.info(f"๋ชจ๋ธ: {CLARITY_MODEL}")
82
+ logger.info(f"SD ๋ชจ๋ธ: {sd_model}")
83
+ logger.info(f"์Šค์ผ€์ผ ํŒฉํ„ฐ: {scale_factor}")
84
+ logger.info(f"์ถœ๋ ฅ ํ˜•์‹: {output_format}")
85
+ logger.info(f"์œ ์‚ฌ๋„: {resemblance}")
86
+ logger.info(f"์ฐฝ์˜์„ฑ: {creativity}")
87
+ logger.info(f"๋‹ค์ด๋‚˜๋ฏน: {dynamic}")
88
+ logger.info(f"์„ ๋ช…๋„: {sharpen}")
89
+ logger.info(f"์‹œ๋“œ: {seed}")
90
+
91
+ # ํ™˜๊ฒฝ๋ณ€์ˆ˜์—์„œ ๊ฐ€์ ธ์˜จ ๋ชจ๋ธ๋กœ API ํ˜ธ์ถœ
92
+ output = replicate.run(
93
+ CLARITY_MODEL,
94
+ input={
95
+ "seed": seed,
96
+ "image": open(temp_input_path, "rb"),
97
+ "prompt": prompt,
98
+ "dynamic": dynamic,
99
+ "handfix": "disabled",
100
+ "pattern": False,
101
+ "sharpen": sharpen,
102
+ "sd_model": sd_model,
103
+ "scheduler": "DPM++ 3M SDE Karras",
104
+ "creativity": creativity,
105
+ "lora_links": "",
106
+ "downscaling": False,
107
+ "resemblance": resemblance,
108
+ "scale_factor": scale_factor,
109
+ "tiling_width": 112,
110
+ "output_format": output_format,
111
+ "tiling_height": 144,
112
+ "custom_sd_model": "",
113
+ "negative_prompt": negative_prompt,
114
+ "num_inference_steps": 18,
115
+ "downscaling_resolution": 768
116
+ }
117
+ )
118
+
119
+ logger.info(f"Replicate API ์‘๋‹ต: {output}")
120
+
121
+ # ๊ฒฐ๊ณผ ์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ ๋ฐ ๋ฐ˜ํ™˜
122
+ if output and isinstance(output, list) and len(output) > 0:
123
+ import requests
124
+ from io import BytesIO
125
+
126
+ response = requests.get(output[0])
127
+ if response.status_code == 200:
128
+ result_image = Image.open(BytesIO(response.content))
129
+
130
+ # JPG๋กœ ๋ณ€ํ™˜ (output_format์ด jpg์ธ ๊ฒฝ์šฐ)
131
+ if output_format.lower() == "jpg":
132
+ temp_output = BytesIO()
133
+ if result_image.mode == 'RGBA':
134
+ result_image = result_image.convert('RGB')
135
+ result_image.save(temp_output, format='JPEG', quality=95)
136
+ temp_output.seek(0)
137
+ result_image = Image.open(temp_output)
138
+
139
+ logger.info("์ด๋ฏธ์ง€ ํ™”์งˆ ๊ฐœ์„  ์™„๋ฃŒ!")
140
+ return result_image
141
+ else:
142
+ logger.error(f"๊ฒฐ๊ณผ ์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ ์‹คํŒจ: {response.status_code}")
143
+ return None
144
+ else:
145
+ logger.error("API ์‘๋‹ต์—์„œ ์ด๋ฏธ์ง€๋ฅผ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")
146
+ return None
147
+
148
+ except Exception as e:
149
+ logger.error(f"ํ™”์งˆ ๊ฐœ์„  ์ค‘ ์˜ค๋ฅ˜ ๋ฐœ์ƒ: {str(e)}")
150
+ raise
151
+ finally:
152
+ # ์ž„์‹œ ํŒŒ์ผ ์ •๋ฆฌ
153
+ if os.path.exists(temp_input_path):
154
+ os.remove(temp_input_path)
155
+
156
+ def process_and_download(
157
+ password, image, scale_factor, output_format, sd_model,
158
+ resemblance, creativity, dynamic, sharpen, seed
159
+ ):
160
+ # ํ™˜๊ฒฝ๋ณ€์ˆ˜์—์„œ ๋น„๋ฐ€๋ฒˆํ˜ธ ๊ฒ€์ฆ
161
+ if not APP_PASSWORD:
162
+ raise ValueError("์„œ๋ฒ„ ์„ค์ • ์˜ค๋ฅ˜์ž…๋‹ˆ๋‹ค. APP_PASSWORD๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.")
163
+
164
+ if password != APP_PASSWORD:
165
+ raise ValueError("์ž˜๋ชป๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ์ž…๋‹ˆ๋‹ค.")
166
+
167
+ if image is None:
168
+ return None, None
169
+
170
+ # ์ด๋ฏธ์ง€ ์—…์Šค์ผ€์ผ
171
+ result_img = upscale_image(
172
+ image=image,
173
+ scale_factor=scale_factor,
174
+ output_format=output_format,
175
+ sd_model=sd_model,
176
+ resemblance=resemblance,
177
+ creativity=creativity,
178
+ dynamic=dynamic,
179
+ sharpen=sharpen,
180
+ seed=int(seed)
181
+ )
182
+ if result_img is None:
183
+ return None, None
184
+
185
+ # ํŒŒ์ผ๋กœ ์ €์žฅ
186
+ ext = "jpg" if output_format.lower() == "jpg" else "png"
187
+ # JPG๋กœ ์ €์žฅํ•  ๋• RGB ๋ชจ๋“œ๋กœ ๋ณ€ํ™˜
188
+ if ext == "jpg" and result_img.mode == "RGBA":
189
+ result_img = result_img.convert("RGB")
190
+
191
+ filename = f"upscaled_{uuid.uuid4()}.{ext}"
192
+ filepath = os.path.join(TEMP_DIR, filename)
193
+ result_img.save(filepath, format="JPEG" if ext=="jpg" else "PNG")
194
+
195
+ # ๋ฆฌํ„ด: (์ด๋ฏธ์ง€, ํŒŒ์ผ ๊ฒฝ๋กœ)
196
+ return result_img, filepath
197
+
198
+ def create_interface():
199
+ with gr.Blocks(title="Clarity Upscaler") as demo:
200
+ with gr.Row():
201
+ with gr.Column():
202
+ password_input = gr.Textbox(
203
+ label="๋น„๋ฐ€๋ฒˆํ˜ธ", type="password", placeholder="๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•˜์„ธ์š”"
204
+ )
205
+ input_image = gr.Image(label="์›๋ณธ ์ด๋ฏธ์ง€", type="pil")
206
+
207
+ with gr.Accordion("๊ณ ๊ธ‰ ์„ค์ •", open=False):
208
+ scale_factor = gr.Slider(1, 4, value=2, step=0.5, label="ํ™•๋Œ€ ๋น„์œจ")
209
+ output_format = gr.Radio(["jpg","png"], value="jpg", label="์ถœ๋ ฅ ํ˜•์‹")
210
+ sd_model = gr.Dropdown(
211
+ choices=[
212
+ "juggernaut_reborn.safetensors [338b85bc4f]",
213
+ "sd_xl_base_1.0.safetensors [39d4e625d]",
214
+ "sdxl_base_v0.9-9961.safetensors [3048045c]",
215
+ "realisticVisionV51_v51VAE.safetensors [5ecbfa0ac]",
216
+ ],
217
+ value="juggernaut_reborn.safetensors [338b85bc4f]",
218
+ label="SD ๋ชจ๋ธ"
219
+ )
220
+ resemblance = gr.Slider(0.0,1.0, value=0.6, step=0.05, label="์›๋ณธ ์œ ์‚ฌ๋„")
221
+ creativity = gr.Slider(0.0,1.0, value=0.35,step=0.05, label="์ฐฝ์˜์„ฑ")
222
+ dynamic = gr.Slider(1,10, value=6, step=1, label="๋‹ค์ด๋‚˜๋ฏน ์ž„๊ณ„๊ฐ’")
223
+ sharpen = gr.Slider(0,2, value=0, step=0.1, label="์„ ๋ช…๋„")
224
+ seed = gr.Number(value=1337, label="์‹œ๋“œ", precision=0)
225
+
226
+ submit_btn = gr.Button("์‹คํ–‰", variant="primary")
227
+
228
+ with gr.Column():
229
+ output_image = gr.Image(label="๊ฐœ์„ ๋œ ์ด๋ฏธ์ง€")
230
+ download_btn = gr.DownloadButton(label="์ด๋ฏธ์ง€ ๋‹ค์šด๋กœ๋“œ")
231
+
232
+ # ํด๋ฆญ ์‹œ ๋‘ ๊ฐœ์˜ ์ถœ๋ ฅ(์ด๋ฏธ์ง€, ํŒŒ์ผ ๊ฒฝ๋กœ)์„ ๋ฐ˜ํ™˜
233
+ submit_btn.click(
234
+ fn=process_and_download,
235
+ inputs=[
236
+ password_input,
237
+ input_image, scale_factor, output_format, sd_model,
238
+ resemblance, creativity, dynamic, sharpen, seed
239
+ ],
240
+ outputs=[output_image, download_btn]
241
+ )
242
+
243
+ return demo
244
+
245
+ if __name__ == "__main__":
246
+ demo = create_interface()
247
+ demo.launch(share=True)