Spaces:
Running
Running
刘宇轩
commited on
Commit
·
3a8ba72
1
Parent(s):
8bf2c1e
Initial Commit
Browse files- .gitignore +13 -0
- app.py +398 -0
- asset/chaojihui-v2.png +0 -0
- asset/chaojihui.png +0 -0
- asset/chaojihui45.png +0 -0
- asset/zhushe.png +0 -0
- db_examples.py +98 -0
- images/dummy.png +0 -0
- images/original_1.jpg +0 -0
- images/original_2.jpg +0 -0
- images/original_3.jpg +0 -0
- images/original_4.jpg +0 -0
- images/reference_1.jpg +0 -0
- images/reference_2.jpg +0 -0
- images/reference_3.jpg +0 -0
- images/reference_4.jpg +0 -0
- images/resimg_1.webp +0 -0
- images/resimg_2.webp +0 -0
- images/resimg_3.webp +0 -0
- images/resimg_4.webp +0 -0
- images/restxt_1.webp +0 -0
- images/restxt_2.webp +0 -0
- images/restxt_3.webp +0 -0
- images/restxt_4.webp +0 -0
- images/restxt_5.webp +0 -0
- images/restxt_6.webp +0 -0
- images/restxt_7.webp +0 -0
- images/restxt_8.webp +0 -0
- ops.py +135 -0
- watermark.py +49 -0
.gitignore
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
ossutil_output
|
2 |
+
__pycache__
|
3 |
+
.DS_Store
|
4 |
+
test.jpg
|
5 |
+
test.py
|
6 |
+
test.sh
|
7 |
+
app.sh
|
8 |
+
__pycache__
|
9 |
+
r1.jpg
|
10 |
+
r2.png
|
11 |
+
r11.png
|
12 |
+
test.jpg
|
13 |
+
temp.py
|
app.py
ADDED
@@ -0,0 +1,398 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import hashlib
|
2 |
+
import time
|
3 |
+
import uuid
|
4 |
+
from urllib.parse import urlencode
|
5 |
+
import json
|
6 |
+
import requests
|
7 |
+
from PIL import Image, ImageOps
|
8 |
+
import os
|
9 |
+
import gradio as gr
|
10 |
+
|
11 |
+
import ops
|
12 |
+
from watermark import WatermarkApp
|
13 |
+
import db_examples
|
14 |
+
|
15 |
+
|
16 |
+
class ApiClient(object):
|
17 |
+
|
18 |
+
def __init__(self, app_key: str, access_key_id: str, access_key_secret: str, endpoint: str):
|
19 |
+
self.app_key = app_key
|
20 |
+
self.access_key_id = access_key_id
|
21 |
+
self.access_key_secret = access_key_secret
|
22 |
+
self.endpoint = endpoint
|
23 |
+
self.base_url = 'http://' + self.endpoint + '/api'
|
24 |
+
self.timeout = 8000
|
25 |
+
self.session = requests.Session()
|
26 |
+
self.session.headers.update(
|
27 |
+
{
|
28 |
+
"Content-Type": "application/json;charset=utf-8",
|
29 |
+
"accessKey": self.access_key_id,
|
30 |
+
"appKey": self.app_key
|
31 |
+
}
|
32 |
+
)
|
33 |
+
|
34 |
+
def send_get(self, headers=None, params=None):
|
35 |
+
if headers is None:
|
36 |
+
headers = {}
|
37 |
+
if params is None:
|
38 |
+
params = {}
|
39 |
+
args = self.cleanNoneValue(
|
40 |
+
{
|
41 |
+
"url": self.base_url,
|
42 |
+
"headers": self._prepare_headers(headers),
|
43 |
+
"params": self._prepare_params(params),
|
44 |
+
"timeout": self.timeout
|
45 |
+
}
|
46 |
+
)
|
47 |
+
response = self._dispatch_request("GET")(**args)
|
48 |
+
self._handle_exception(response)
|
49 |
+
try:
|
50 |
+
data = response.json()
|
51 |
+
except ValueError:
|
52 |
+
data = response.text
|
53 |
+
return data
|
54 |
+
|
55 |
+
def send_post(self, headers=None, params=None):
|
56 |
+
if headers is None:
|
57 |
+
headers = {}
|
58 |
+
if params is None:
|
59 |
+
params = {}
|
60 |
+
args = self.cleanNoneValue(
|
61 |
+
{
|
62 |
+
"url": self.base_url,
|
63 |
+
"headers": self._prepare_headers(headers),
|
64 |
+
"json": params,
|
65 |
+
"timeout": self.timeout
|
66 |
+
}
|
67 |
+
)
|
68 |
+
response = self._dispatch_request("POST")(**args)
|
69 |
+
self._handle_exception(response)
|
70 |
+
try:
|
71 |
+
data = response.json()
|
72 |
+
except ValueError:
|
73 |
+
data = response.text
|
74 |
+
return data
|
75 |
+
|
76 |
+
def _prepare_headers(self, headers):
|
77 |
+
headers['requestId'] = str(uuid.uuid1())
|
78 |
+
timestamp = int(round(time.time() * 1000))
|
79 |
+
headers['timestamp'] = str(timestamp)
|
80 |
+
headers['sign'] = self._get_sign(timestamp)
|
81 |
+
return headers
|
82 |
+
|
83 |
+
def _prepare_params(self, params):
|
84 |
+
return self.encoded_string(self.cleanNoneValue(params))
|
85 |
+
|
86 |
+
def _get_sign(self, timestamp):
|
87 |
+
key = self.app_key + self.access_key_id + str(timestamp) + self.access_key_secret
|
88 |
+
md5hash = hashlib.md5(str.encode(key, 'utf-8'))
|
89 |
+
return md5hash.hexdigest()
|
90 |
+
|
91 |
+
def _dispatch_request(self, http_method):
|
92 |
+
return {
|
93 |
+
"GET": self.session.get,
|
94 |
+
"DELETE": self.session.delete,
|
95 |
+
"PUT": self.session.put,
|
96 |
+
"POST": self.session.post,
|
97 |
+
}.get(http_method, "GET")
|
98 |
+
|
99 |
+
def _handle_exception(self, response):
|
100 |
+
status_code = response.status_code
|
101 |
+
if status_code < 400:
|
102 |
+
return
|
103 |
+
raise Exception(response.text)
|
104 |
+
|
105 |
+
def encoded_string(self, query):
|
106 |
+
|
107 |
+
return urlencode(query, True).replace("%40", "@")
|
108 |
+
|
109 |
+
def cleanNoneValue(self, d) -> dict:
|
110 |
+
out = {}
|
111 |
+
for k in d.keys():
|
112 |
+
if d[k] is not None:
|
113 |
+
out[k] = d[k]
|
114 |
+
return out
|
115 |
+
|
116 |
+
|
117 |
+
api_key = os.environ['APIKEY']
|
118 |
+
ak = os.environ['AK']
|
119 |
+
sk = os.environ['SK']
|
120 |
+
endpoint = os.environ['ENDPOINT']
|
121 |
+
apiname = os.environ['APINAME']
|
122 |
+
callbackapiname = os.environ['CALLBACKAPINAME']
|
123 |
+
osssigneapiname = os.environ['OSSSIGNAPINAME']
|
124 |
+
|
125 |
+
client = ApiClient(api_key, ak, sk, endpoint)
|
126 |
+
watermark_app = WatermarkApp()
|
127 |
+
|
128 |
+
def upload_to_oss(file_path, accessid, policy, signature, host, key, callback):
|
129 |
+
with open(file_path, 'rb') as f:
|
130 |
+
files = {'file': (key, f)}
|
131 |
+
data = {
|
132 |
+
'OSSAccessKeyId': accessid,
|
133 |
+
'policy': policy,
|
134 |
+
'Signature': signature,
|
135 |
+
'key': key,
|
136 |
+
'callback': callback,
|
137 |
+
}
|
138 |
+
response = requests.post(host, files=files, data=data)
|
139 |
+
if response.status_code == 204 or response.ok:
|
140 |
+
return key
|
141 |
+
else:
|
142 |
+
print(f"file upload failed: {response.text}")
|
143 |
+
return None
|
144 |
+
|
145 |
+
|
146 |
+
def upload_oss_bucket(image_pil):
|
147 |
+
headers = {
|
148 |
+
'apiName': osssigneapiname
|
149 |
+
}
|
150 |
+
params = {
|
151 |
+
'fileType': '1'
|
152 |
+
}
|
153 |
+
result = client.send_get(headers, params)
|
154 |
+
try:
|
155 |
+
result = result['data']
|
156 |
+
except Exception as e:
|
157 |
+
raise ValueError('oss sign error')
|
158 |
+
accessid = result['accessid']
|
159 |
+
policy = result['policy']
|
160 |
+
signature = result['signature']
|
161 |
+
host = result['host']
|
162 |
+
callback = ''
|
163 |
+
oss_key = os.path.join(result['dir'], '{}.jpg'.format(result['expire']))
|
164 |
+
file_path = 'test.jpg'
|
165 |
+
image_pil.save(file_path)
|
166 |
+
oss_key = upload_to_oss(file_path, accessid, policy, signature, host, oss_key, callback)
|
167 |
+
if oss_key is None:
|
168 |
+
raise ValueError('oss upload error')
|
169 |
+
return oss_key
|
170 |
+
|
171 |
+
|
172 |
+
def call_text_guided_relighting(image, mode, prompt, seed, steps):
|
173 |
+
headers = {
|
174 |
+
'apiName': apiname
|
175 |
+
}
|
176 |
+
image = ImageOps.exif_transpose(image).convert('RGB')
|
177 |
+
image = ops.resize_keep_hw_rate(image, tar_res=1280)
|
178 |
+
image = upload_oss_bucket(image)
|
179 |
+
ops.print_with_datetime('start call_text_guided_relighting')
|
180 |
+
ops.print_with_datetime(prompt)
|
181 |
+
params = {
|
182 |
+
'image': image,
|
183 |
+
'inference_mode': 'free_txt2bg_gen',
|
184 |
+
'mode': mode,
|
185 |
+
'prompt': prompt,
|
186 |
+
'seed': seed,
|
187 |
+
'steps': steps,
|
188 |
+
}
|
189 |
+
ops.print_with_datetime(f'length params, {len(json.dumps(params))}')
|
190 |
+
task_id = client.send_post(headers, params)['data']
|
191 |
+
time.sleep(10)
|
192 |
+
headers = {
|
193 |
+
'apiName': callbackapiname
|
194 |
+
}
|
195 |
+
params = {
|
196 |
+
'id': task_id
|
197 |
+
}
|
198 |
+
flag = True
|
199 |
+
while flag:
|
200 |
+
result = client.send_get(headers, params)['data']
|
201 |
+
if result['status'] != 1:
|
202 |
+
flag = False
|
203 |
+
else:
|
204 |
+
time.sleep(10)
|
205 |
+
if result['status'] != 2:
|
206 |
+
raise ValueError('something wrong in the process')
|
207 |
+
|
208 |
+
result_1 = result['sasMyCreationPicVOs'][0]['picUrl']
|
209 |
+
result_2 = result['sasMyCreationPicVOs'][0]['maskUrl']
|
210 |
+
result_1 = ops.decode_img_from_url(result_1)
|
211 |
+
result_1 = watermark_app.process_image(result_1)
|
212 |
+
result_2 = ops.decode_img_from_url(result_2)
|
213 |
+
return result_1, result_2
|
214 |
+
|
215 |
+
|
216 |
+
def call_image_guided_relighting(image, ref_img, seed, steps):
|
217 |
+
headers = {
|
218 |
+
'apiName': apiname
|
219 |
+
}
|
220 |
+
image = ImageOps.exif_transpose(image).convert('RGB')
|
221 |
+
image = ops.resize_keep_hw_rate(image, tar_res=1280)
|
222 |
+
image = upload_oss_bucket(image)
|
223 |
+
|
224 |
+
ref_img = ImageOps.exif_transpose(ref_img).convert('RGB')
|
225 |
+
ref_img = ops.resize_keep_hw_rate(ref_img, tar_res=1280)
|
226 |
+
ref_img = upload_oss_bucket(ref_img)
|
227 |
+
|
228 |
+
ops.print_with_datetime('start call_image_guided_relighting')
|
229 |
+
params = {
|
230 |
+
'image': image,
|
231 |
+
'inference_mode': 'replica_gen',
|
232 |
+
'mode': 'normal',
|
233 |
+
'ref_img': ref_img,
|
234 |
+
'seed': seed,
|
235 |
+
'steps': steps,
|
236 |
+
}
|
237 |
+
ops.print_with_datetime(f'length params, {len(json.dumps(params))}')
|
238 |
+
task_id = client.send_post(headers, params)
|
239 |
+
print(task_id)
|
240 |
+
task_id = task_id['data']
|
241 |
+
time.sleep(10)
|
242 |
+
headers = {
|
243 |
+
'apiName': callbackapiname
|
244 |
+
}
|
245 |
+
params = {
|
246 |
+
'id': task_id
|
247 |
+
}
|
248 |
+
flag = True
|
249 |
+
while flag:
|
250 |
+
result = client.send_get(headers, params)
|
251 |
+
result = result['data']
|
252 |
+
if result['status'] != 1:
|
253 |
+
flag = False
|
254 |
+
else:
|
255 |
+
time.sleep(10)
|
256 |
+
if result['status'] != 2:
|
257 |
+
raise ValueError('something wrong in the process')
|
258 |
+
|
259 |
+
result_1 = result['sasMyCreationPicVOs'][0]['picUrl']
|
260 |
+
result_2 = result['sasMyCreationPicVOs'][0]['maskUrl']
|
261 |
+
result_1 = ops.decode_img_from_url(result_1)
|
262 |
+
result_1 = watermark_app.process_image(result_1)
|
263 |
+
result_2 = ops.decode_img_from_url(result_2)
|
264 |
+
return result_1, result_2
|
265 |
+
|
266 |
+
|
267 |
+
|
268 |
+
quick_prompts = [
|
269 |
+
'warm lighting',
|
270 |
+
'sunshine from window',
|
271 |
+
'neon lighting',
|
272 |
+
'at noon. bright sunlight',
|
273 |
+
'at dusk',
|
274 |
+
'golden time',
|
275 |
+
'natural lighting',
|
276 |
+
'shadow from window',
|
277 |
+
'soft studio lighting',
|
278 |
+
'red lighting',
|
279 |
+
'purple lighting'
|
280 |
+
]
|
281 |
+
quick_prompts = [[x] for x in quick_prompts]
|
282 |
+
|
283 |
+
|
284 |
+
quick_content_prompts = [
|
285 |
+
'by the sea',
|
286 |
+
'in the forest',
|
287 |
+
'on the snow mountain',
|
288 |
+
'by the city street',
|
289 |
+
'on the grassy field',
|
290 |
+
'cityscape',
|
291 |
+
'on the desert',
|
292 |
+
'in the living room',
|
293 |
+
]
|
294 |
+
quick_content_prompts = [[x] for x in quick_content_prompts]
|
295 |
+
|
296 |
+
|
297 |
+
quick_subjects = [
|
298 |
+
'portrait photography of a woman',
|
299 |
+
'portrait photography of man',
|
300 |
+
'product photography',
|
301 |
+
]
|
302 |
+
quick_subjects = [[x] for x in quick_subjects]
|
303 |
+
|
304 |
+
|
305 |
+
with gr.Blocks().queue() as demo:
|
306 |
+
gr.HTML("""
|
307 |
+
<div style="text-align: center; font-size: 32px; font-weight: bold; margin-bottom: 20px;">
|
308 |
+
FreeLighting: relighting model with both text-condition and image-condition
|
309 |
+
</div>
|
310 |
+
""")
|
311 |
+
with gr.Row():
|
312 |
+
gr.Markdown("See more information in https://github.com/liuyuxuan3060/FreeLighting")
|
313 |
+
with gr.Row():
|
314 |
+
gr.Markdown("We use a open source segmentation model to generate image mask")
|
315 |
+
|
316 |
+
with gr.Tabs():
|
317 |
+
with gr.TabItem("text-guided relighting") as t2v_tab:
|
318 |
+
with gr.Row():
|
319 |
+
with gr.Column():
|
320 |
+
with gr.Row():
|
321 |
+
image = gr.Image(label="original_image", type="pil", height=480)
|
322 |
+
image_mask = gr.Image(label="image_mask", type="pil", height=480)
|
323 |
+
with gr.Row():
|
324 |
+
prompt = gr.Textbox(value="", label="text prompt")
|
325 |
+
with gr.Row():
|
326 |
+
mode = gr.Radio(choices=["normal", "uniform-lit"], value='normal', label="uniform-lit mode will use double time", type='value')
|
327 |
+
seed = gr.Number(value=12345, label="random seed", precision=0)
|
328 |
+
steps = gr.Slider(label="Steps", minimum=1, maximum=100, value=20, step=1)
|
329 |
+
button = gr.Button("generate")
|
330 |
+
|
331 |
+
with gr.Row():
|
332 |
+
example_quick_subjects = gr.Dataset(samples=quick_subjects, label='Subject Quick List', samples_per_page=1000, components=[prompt])
|
333 |
+
with gr.Row():
|
334 |
+
example_quick_prompts = gr.Dataset(samples=quick_prompts, label='Lighting Quick List', samples_per_page=1000, components=[prompt])
|
335 |
+
with gr.Row():
|
336 |
+
example_quick_content_prompts = gr.Dataset(samples=quick_content_prompts, label='Content Quick List', samples_per_page=1000, components=[prompt])
|
337 |
+
with gr.Column():
|
338 |
+
relighting_image = gr.Image(label="relighted_image", type="pil", height=480)
|
339 |
+
|
340 |
+
with gr.Row():
|
341 |
+
gr.Examples(
|
342 |
+
examples=db_examples.text_guided_examples,
|
343 |
+
inputs=[
|
344 |
+
image, mode, prompt, seed, steps
|
345 |
+
, relighting_image
|
346 |
+
],
|
347 |
+
outputs=[relighting_image],
|
348 |
+
examples_per_page=1024
|
349 |
+
)
|
350 |
+
|
351 |
+
button.click(
|
352 |
+
fn=call_text_guided_relighting,
|
353 |
+
inputs=[
|
354 |
+
image, mode, prompt, seed, steps
|
355 |
+
],
|
356 |
+
outputs=[relighting_image, image_mask],
|
357 |
+
)
|
358 |
+
example_quick_content_prompts.click(lambda x, y: ', '.join(y.split(', ')[:2] + [x[0]]), inputs=[example_quick_content_prompts, prompt], outputs=prompt, show_progress=False, queue=False)
|
359 |
+
example_quick_prompts.click(lambda x, y: ', '.join(y.split(', ')[:2] + [x[0]]), inputs=[example_quick_prompts, prompt], outputs=prompt, show_progress=False, queue=False)
|
360 |
+
example_quick_subjects.click(lambda x: x[0], inputs=example_quick_subjects, outputs=prompt, show_progress=False, queue=False)
|
361 |
+
|
362 |
+
with gr.TabItem("image-guided relighting") as i2v_tab:
|
363 |
+
with gr.Row():
|
364 |
+
with gr.Column():
|
365 |
+
with gr.Row():
|
366 |
+
image = gr.Image(label="original_image", type="pil", height=480)
|
367 |
+
ref_img = gr.Image(label="reference_image", type="pil", height=480)
|
368 |
+
image_mask = gr.Image(label="image_mask", type="pil", height=480)
|
369 |
+
with gr.Row():
|
370 |
+
seed = gr.Number(value=12345, label="random seed", precision=0)
|
371 |
+
steps = gr.Slider(label="Steps", minimum=1, maximum=100, value=20, step=1)
|
372 |
+
button = gr.Button("generate")
|
373 |
+
with gr.Column():
|
374 |
+
relighting_image = gr.Image(label="relighted_image", type="pil", height=480)
|
375 |
+
|
376 |
+
with gr.Row():
|
377 |
+
gr.Examples(
|
378 |
+
examples=db_examples.image_guided_examples,
|
379 |
+
inputs=[
|
380 |
+
image, ref_img, seed, steps
|
381 |
+
, relighting_image
|
382 |
+
],
|
383 |
+
outputs=[relighting_image],
|
384 |
+
examples_per_page=1024
|
385 |
+
)
|
386 |
+
|
387 |
+
button.click(
|
388 |
+
fn=call_image_guided_relighting,
|
389 |
+
inputs=[
|
390 |
+
image, ref_img, seed, steps
|
391 |
+
],
|
392 |
+
outputs=[relighting_image, image_mask],
|
393 |
+
)
|
394 |
+
|
395 |
+
|
396 |
+
demo.launch()
|
397 |
+
|
398 |
+
|
asset/chaojihui-v2.png
ADDED
![]() |
asset/chaojihui.png
ADDED
![]() |
asset/chaojihui45.png
ADDED
![]() |
asset/zhushe.png
ADDED
![]() |
db_examples.py
ADDED
@@ -0,0 +1,98 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
text_guided_examples = [
|
2 |
+
[
|
3 |
+
'images/original_1.jpg',
|
4 |
+
'uniform-lit',
|
5 |
+
'portrait photography of a woman, at noon. bright sunlight, by the sea',
|
6 |
+
1,
|
7 |
+
20,
|
8 |
+
'images/restxt_1.webp',
|
9 |
+
],
|
10 |
+
[
|
11 |
+
'images/original_1.jpg',
|
12 |
+
'uniform-lit',
|
13 |
+
'portrait photography of a woman, neon lighting, by the city street',
|
14 |
+
1,
|
15 |
+
20,
|
16 |
+
'images/restxt_2.webp',
|
17 |
+
],
|
18 |
+
[
|
19 |
+
'images/original_2.jpg',
|
20 |
+
'normal',
|
21 |
+
'portrait photography of a woman, purple lighting, in the living room',
|
22 |
+
1,
|
23 |
+
20,
|
24 |
+
'images/restxt_3.webp',
|
25 |
+
],
|
26 |
+
[
|
27 |
+
'images/original_2.jpg',
|
28 |
+
'normal',
|
29 |
+
'portrait photography of a woman, warm lighting, on the desert',
|
30 |
+
1,
|
31 |
+
20,
|
32 |
+
'images/restxt_4.webp',
|
33 |
+
],
|
34 |
+
[
|
35 |
+
'images/original_3.jpg',
|
36 |
+
'uniform-lit',
|
37 |
+
'portrait photography of a woman, at noon. bright sunlight, cityscape',
|
38 |
+
1,
|
39 |
+
20,
|
40 |
+
'images/restxt_5.webp',
|
41 |
+
],
|
42 |
+
[
|
43 |
+
'images/original_3.jpg',
|
44 |
+
'normal',
|
45 |
+
'portrait photography of a woman, at noon. bright sunlight, cityscape',
|
46 |
+
1,
|
47 |
+
20,
|
48 |
+
'images/restxt_6.webp',
|
49 |
+
],
|
50 |
+
[
|
51 |
+
'images/original_4.jpg',
|
52 |
+
'normal',
|
53 |
+
'portrait photography of a woman, at noon. bright sunlight, cityscape',
|
54 |
+
1,
|
55 |
+
20,
|
56 |
+
'images/restxt_7.webp',
|
57 |
+
],
|
58 |
+
[
|
59 |
+
'images/original_4.jpg',
|
60 |
+
'normal',
|
61 |
+
'portrait photography of a woman, neon lighting, by the city street',
|
62 |
+
1,
|
63 |
+
20,
|
64 |
+
'images/restxt_8.webp',
|
65 |
+
],
|
66 |
+
]
|
67 |
+
|
68 |
+
image_guided_examples = [
|
69 |
+
[
|
70 |
+
'images/original_1.jpg',
|
71 |
+
'images/reference_2.jpg',
|
72 |
+
12345,
|
73 |
+
20,
|
74 |
+
'images/resimg_1.webp',
|
75 |
+
],
|
76 |
+
[
|
77 |
+
'images/original_3.jpg',
|
78 |
+
'images/reference_4.jpg',
|
79 |
+
12345,
|
80 |
+
20,
|
81 |
+
'images/resimg_2.webp',
|
82 |
+
],
|
83 |
+
[
|
84 |
+
'images/original_4.jpg',
|
85 |
+
'images/reference_3.jpg',
|
86 |
+
12345,
|
87 |
+
20,
|
88 |
+
'images/resimg_3.webp',
|
89 |
+
],
|
90 |
+
[
|
91 |
+
'images/original_2.jpg',
|
92 |
+
'images/reference_3.jpg',
|
93 |
+
12345,
|
94 |
+
20,
|
95 |
+
'images/resimg_4.webp',
|
96 |
+
],
|
97 |
+
]
|
98 |
+
|
images/dummy.png
ADDED
![]() |
images/original_1.jpg
ADDED
![]() |
images/original_2.jpg
ADDED
![]() |
images/original_3.jpg
ADDED
![]() |
images/original_4.jpg
ADDED
![]() |
images/reference_1.jpg
ADDED
![]() |
images/reference_2.jpg
ADDED
![]() |
images/reference_3.jpg
ADDED
![]() |
images/reference_4.jpg
ADDED
![]() |
images/resimg_1.webp
ADDED
![]() |
images/resimg_2.webp
ADDED
![]() |
images/resimg_3.webp
ADDED
![]() |
images/resimg_4.webp
ADDED
![]() |
images/restxt_1.webp
ADDED
![]() |
images/restxt_2.webp
ADDED
![]() |
images/restxt_3.webp
ADDED
![]() |
images/restxt_4.webp
ADDED
![]() |
images/restxt_5.webp
ADDED
![]() |
images/restxt_6.webp
ADDED
![]() |
images/restxt_7.webp
ADDED
![]() |
images/restxt_8.webp
ADDED
![]() |
ops.py
ADDED
@@ -0,0 +1,135 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import base64
|
2 |
+
import numpy as np
|
3 |
+
import cv2
|
4 |
+
import json
|
5 |
+
import pickle
|
6 |
+
import itertools
|
7 |
+
import requests
|
8 |
+
from io import StringIO
|
9 |
+
|
10 |
+
from io import BytesIO
|
11 |
+
import re, os
|
12 |
+
from PIL import Image
|
13 |
+
from datetime import datetime
|
14 |
+
import random
|
15 |
+
|
16 |
+
import torch
|
17 |
+
|
18 |
+
import socket
|
19 |
+
r_b64_prefix = r'^data:image/.+;base64,'
|
20 |
+
|
21 |
+
from PIL import ImageOps
|
22 |
+
import oss2
|
23 |
+
|
24 |
+
|
25 |
+
class OSS2:
|
26 |
+
def __init__(self, bucket):
|
27 |
+
self.bucket = bucket
|
28 |
+
|
29 |
+
def get_download(self, object_name, download_name=None, minute=5):
|
30 |
+
"""
|
31 |
+
获取文件下载地址
|
32 |
+
:param object_name: OSS 路径
|
33 |
+
:param download_name: 下载重命名
|
34 |
+
:param minute: 请求超时时间
|
35 |
+
:return: 授权URL
|
36 |
+
"""
|
37 |
+
params = None
|
38 |
+
if download_name:
|
39 |
+
params = {"response-content-disposition": 'attachment;filename="{0}"'.format(quote(download_name, 'utf-8'))}
|
40 |
+
url = self.bucket.sign_url('GET', object_name, minute * 60, params=params)
|
41 |
+
return url
|
42 |
+
|
43 |
+
|
44 |
+
|
45 |
+
|
46 |
+
|
47 |
+
def _pil_image_push_ossdir(bucket, image_pil, object_key, quality=85, format='jpeg'):
|
48 |
+
import io
|
49 |
+
print_with_datetime('upload object_key {}'.format(object_key))
|
50 |
+
oss_path = None
|
51 |
+
for _ in range(5):
|
52 |
+
try:
|
53 |
+
img_byte_arr = io.BytesIO()
|
54 |
+
image_pil.save(img_byte_arr, format=format, quality=quality) # 根据实际图片格式选择保存格式
|
55 |
+
img_byte_arr.seek(0) # 回到开始位置
|
56 |
+
bucket.put_object(object_key, img_byte_arr)
|
57 |
+
oss_path = object_key
|
58 |
+
return oss_path
|
59 |
+
except Exception as e:
|
60 |
+
print_with_datetime('error, upload oss failed, {}'.format(str(e)))
|
61 |
+
return oss_path
|
62 |
+
|
63 |
+
|
64 |
+
|
65 |
+
def resize_keep_hw_rate(image, tar_res):
|
66 |
+
w, h = image.size
|
67 |
+
if w > h:
|
68 |
+
tar_w = tar_res
|
69 |
+
tar_h = int(tar_w * h / w)
|
70 |
+
elif h > w:
|
71 |
+
tar_h = tar_res
|
72 |
+
tar_w = int(tar_h * w / h)
|
73 |
+
else:
|
74 |
+
tar_w = tar_res
|
75 |
+
tar_h = tar_res
|
76 |
+
image = image.resize((tar_w, tar_h), Image.LANCZOS)
|
77 |
+
return image
|
78 |
+
|
79 |
+
|
80 |
+
def decode_img_from_url(url):
|
81 |
+
import requests
|
82 |
+
from io import BytesIO
|
83 |
+
for _ in range(5):
|
84 |
+
try:
|
85 |
+
content = requests.get(url, stream=True, timeout=10).content
|
86 |
+
img = Image.open(BytesIO(content))
|
87 |
+
img = ImageOps.exif_transpose(img)
|
88 |
+
break
|
89 |
+
except Exception as e:
|
90 |
+
print_with_datetime(f"url decode error {url} {str(e)}")
|
91 |
+
img = None
|
92 |
+
return img
|
93 |
+
|
94 |
+
|
95 |
+
def make_sub_file_folder(file_path):
|
96 |
+
subdir = file_path.split(os.path.basename(file_path))[0]
|
97 |
+
os.makedirs(subdir, exist_ok=True)
|
98 |
+
|
99 |
+
|
100 |
+
def get_random_file_name():
|
101 |
+
timing_cur = datetime.now().timestamp() * 1000000
|
102 |
+
timing_cur = str(int(timing_cur)) + f'-{random.randint(0,99999999)}'
|
103 |
+
return timing_cur
|
104 |
+
|
105 |
+
|
106 |
+
def print_with_datetime(string):
|
107 |
+
print(f'{datetime.now().strftime("%Y-%m-%d %H:%M:%S")}: {string}', flush=True)
|
108 |
+
|
109 |
+
|
110 |
+
def b64_pil(base64Data, mode = 'RGB'):
|
111 |
+
try:
|
112 |
+
base64Data = re.sub(r_b64_prefix, '', base64Data)
|
113 |
+
imgData = base64.b64decode(base64Data)
|
114 |
+
image = Image.open(BytesIO(imgData))
|
115 |
+
except:
|
116 |
+
image = None
|
117 |
+
return image
|
118 |
+
|
119 |
+
|
120 |
+
def pil_b64(pil_img, fmt='jpeg', quality=75):
|
121 |
+
output_buffer = BytesIO()
|
122 |
+
pil_img.save(output_buffer, format=fmt, quality=quality)
|
123 |
+
byte_data = output_buffer.getvalue()
|
124 |
+
base64_str = base64.b64encode(byte_data).decode('utf-8')
|
125 |
+
if fmt == 'jpeg':
|
126 |
+
fmt_out = 'jpg'
|
127 |
+
else:
|
128 |
+
fmt_out = fmt
|
129 |
+
return f'data:image/{fmt_out};base64,' + base64_str
|
130 |
+
|
131 |
+
|
132 |
+
def get_ip():
|
133 |
+
hostname = socket.gethostname()
|
134 |
+
ip_address = socket.gethostbyname(hostname)
|
135 |
+
return ip_address
|
watermark.py
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import oss2
|
3 |
+
from PIL import Image
|
4 |
+
import gradio as gr
|
5 |
+
import numpy as np
|
6 |
+
from io import BytesIO
|
7 |
+
|
8 |
+
|
9 |
+
|
10 |
+
class WatermarkApp:
|
11 |
+
def __init__(self):
|
12 |
+
pass
|
13 |
+
|
14 |
+
def process_image(self, image):
|
15 |
+
watermark = Image.open('asset/chaojihui-v2.png')
|
16 |
+
# 获取水印的等比例缩放尺寸
|
17 |
+
wm_width, wm_height = watermark.size
|
18 |
+
target_size = 100
|
19 |
+
alpha = 0.3
|
20 |
+
|
21 |
+
if wm_width > wm_height:
|
22 |
+
new_wm_width = target_size
|
23 |
+
new_wm_height = int((wm_height / wm_width) * target_size)
|
24 |
+
else:
|
25 |
+
new_wm_height = target_size
|
26 |
+
new_wm_width = int((wm_width / wm_height) * target_size)
|
27 |
+
|
28 |
+
wm = watermark.resize((new_wm_width, new_wm_height), Image.Resampling.LANCZOS)
|
29 |
+
|
30 |
+
# 处理透明度
|
31 |
+
if alpha < 1.0:
|
32 |
+
wm = self.apply_transparency(wm, alpha)
|
33 |
+
|
34 |
+
# 确保原图是RGBA模式
|
35 |
+
if image.mode != 'RGBA':
|
36 |
+
image = image.convert('RGBA')
|
37 |
+
|
38 |
+
# 在整个图片上铺满水印
|
39 |
+
for y in range(0, image.height, new_wm_height):
|
40 |
+
for x in range(0, image.width, new_wm_width):
|
41 |
+
image.alpha_composite(wm, dest=(x, y))
|
42 |
+
return image
|
43 |
+
|
44 |
+
def apply_transparency(self, watermark, alpha):
|
45 |
+
"""应用透明度"""
|
46 |
+
matrix = watermark.split()[-1].point(lambda x: x * alpha)
|
47 |
+
watermark.putalpha(matrix)
|
48 |
+
return watermark
|
49 |
+
|