selfit-camera commited on
Commit
9aefdc2
·
1 Parent(s): c276a99
Files changed (1) hide show
  1. util.py +115 -113
util.py CHANGED
@@ -12,6 +12,7 @@ import numpy as np
12
  import gradio as gr
13
  import boto3
14
  import tempfile
 
15
  from botocore.client import Config
16
  from PIL import Image
17
 
@@ -31,43 +32,45 @@ R2_SECRET_KEY = OneKey[5]
31
  R2_ENDPOINT = OneKey[6]
32
 
33
 
34
- tmpFolder = "tmp"
35
- os.makedirs(tmpFolder, exist_ok=True)
36
-
37
-
38
- def upload_user_img(clientIp, timeId, img):
39
- fileName = clientIp.replace(".", "")+str(timeId)+".jpg"
40
- local_path = os.path.join(tmpFolder, fileName)
41
- img = cv2.imread(img)
42
- cv2.imwrite(os.path.join(tmpFolder, fileName), img)
43
-
44
- json_data = {
45
- "token": TOKEN,
46
- "input1": fileName,
47
- "input2": "",
48
- "protocol": "",
49
- "cloud": "ali"
50
- }
51
-
52
- session = requests.session()
53
- ret = requests.post(
54
- f"{UKAPIURL}/upload",
55
- headers={'Content-Type': 'application/json'},
56
- json=json_data
57
- )
58
-
59
- res = ""
60
- if ret.status_code==200:
61
- if 'upload1' in ret.json():
62
- upload_url = ret.json()['upload1']
63
- headers = {'Content-Type': 'image/jpeg'}
64
- response = session.put(upload_url, data=open(local_path, 'rb').read(), headers=headers)
65
- # print(response.status_code)
66
- if response.status_code == 200:
67
- res = upload_url
68
- if os.path.exists(local_path):
69
- os.remove(local_path)
70
- return res
 
 
71
 
72
 
73
  class R2Api:
@@ -90,6 +93,41 @@ class R2Api:
90
 
91
  self.session = requests.Session() if session is None else session
92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  def upload_file(self, local_path, cloud_path):
94
  t1 = time.time()
95
  head_dict = {
@@ -127,16 +165,29 @@ class R2Api:
127
  print("upload_file time is ====>", time.time() - t1)
128
  return f"{self.domain}{cloud_path}"
129
 
130
- def upload_user_img_r2(clientIp, timeId, img):
 
 
 
 
 
 
 
 
 
 
 
131
  fileName = clientIp.replace(".", "")+str(timeId)+".jpg"
132
- local_path = os.path.join(tmpFolder, fileName)
133
- img = cv2.imread(img)
134
- cv2.imwrite(os.path.join(tmpFolder, fileName), img)
135
-
136
- res = R2Api().upload_file(local_path, fileName)
137
-
138
- if os.path.exists(local_path):
139
- os.remove(local_path)
 
 
140
  return res
141
 
142
 
@@ -203,7 +254,7 @@ def create_mask_from_layers(base_image, layers):
203
 
204
  def upload_mask_image_r2(client_ip, time_id, mask_image):
205
  """
206
- Upload mask image to R2
207
 
208
  Args:
209
  client_ip (str): Client IP
@@ -214,23 +265,20 @@ def upload_mask_image_r2(client_ip, time_id, mask_image):
214
  str: Uploaded URL
215
  """
216
  file_name = f"{client_ip.replace('.', '')}{time_id}_mask.png"
217
- local_path = os.path.join(tmpFolder, file_name)
218
 
219
  try:
220
- # Save mask image as PNG format (supports transparency)
221
- mask_image.save(local_path, 'PNG')
 
 
222
 
223
- # Upload to R2
224
- res = R2Api().upload_file(local_path, file_name)
225
 
226
  return res
227
  except Exception as e:
228
  print(f"Failed to upload mask image: {e}")
229
  return None
230
- finally:
231
- # Clean up local files
232
- if os.path.exists(local_path):
233
- os.remove(local_path)
234
 
235
 
236
 
@@ -313,7 +361,6 @@ def process_image_edit(img_input, prompt, progress_callback=None):
313
  prompt: Editing instructions
314
  progress_callback: Progress callback function
315
  """
316
- temp_img_path = None
317
  try:
318
  # Generate client IP and timestamp
319
  client_ip = "127.0.0.1" # Default IP
@@ -321,26 +368,18 @@ def process_image_edit(img_input, prompt, progress_callback=None):
321
 
322
  # Process input image - supports PIL Image and file path
323
  if hasattr(img_input, 'save'): # PIL Image object
324
- # Create temporary file
325
- temp_dir = tempfile.mkdtemp()
326
- temp_img_path = os.path.join(temp_dir, f"temp_img_{time_id}.jpg")
327
-
328
- # Save PIL Image as temporary file
329
- if img_input.mode != 'RGB':
330
- img_input = img_input.convert('RGB')
331
- img_input.save(temp_img_path, 'JPEG', quality=95)
332
-
333
- img_path = temp_img_path
334
- print(f"💾 PIL Image saved as temporary file: {temp_img_path}")
335
  else:
336
- # Assume it's a file path
337
- img_path = img_input
 
338
 
339
  if progress_callback:
340
  progress_callback("uploading image...")
341
 
342
- # Upload user image
343
- uploaded_url = upload_user_img_r2(client_ip, time_id, img_path)
344
  if not uploaded_url:
345
  return None, "image upload failed"
346
 
@@ -374,7 +413,7 @@ def process_image_edit(img_input, prompt, progress_callback=None):
374
  elif status in ['queued', 'processing', 'running', 'created', 'working']:
375
  if progress_callback:
376
  progress_callback(f"task processing... (status: {status})")
377
- time.sleep(1) # 等待10秒后重试
378
  else:
379
  if progress_callback:
380
  progress_callback(f"unknown status: {status}")
@@ -384,19 +423,6 @@ def process_image_edit(img_input, prompt, progress_callback=None):
384
 
385
  except Exception as e:
386
  return None, f"error occurred during processing: {str(e)}"
387
-
388
- finally:
389
- # 清理临时文件
390
- if temp_img_path and os.path.exists(temp_img_path):
391
- try:
392
- os.remove(temp_img_path)
393
- # 尝试删除临时目录(如果为空)
394
- temp_dir = os.path.dirname(temp_img_path)
395
- if os.path.exists(temp_dir):
396
- os.rmdir(temp_dir)
397
- print(f"🗑️ Cleaned up temporary file: {temp_img_path}")
398
- except Exception as cleanup_error:
399
- print(f"⚠️ Failed to clean up temporary file: {cleanup_error}")
400
 
401
 
402
  def process_local_image_edit(base_image, layers, prompt, progress_callback=None):
@@ -409,9 +435,6 @@ def process_local_image_edit(base_image, layers, prompt, progress_callback=None)
409
  prompt (str): 编辑指令
410
  progress_callback: 进度回调函数
411
  """
412
- temp_img_path = None
413
- temp_mask_path = None
414
-
415
  try:
416
  # Generate client IP and timestamp
417
  client_ip = "127.0.0.1" # Default IP
@@ -433,17 +456,8 @@ def process_local_image_edit(base_image, layers, prompt, progress_callback=None)
433
  if progress_callback:
434
  progress_callback("uploading original image...")
435
 
436
- # 处理并上传原始图片
437
- temp_dir = tempfile.mkdtemp()
438
- temp_img_path = os.path.join(temp_dir, f"temp_img_{time_id}.jpg")
439
-
440
- # 保存原始图片
441
- if base_image.mode != 'RGB':
442
- base_image = base_image.convert('RGB')
443
- base_image.save(temp_img_path, 'JPEG', quality=95)
444
-
445
- # 上传原始图片
446
- uploaded_url = upload_user_img_r2(client_ip, time_id, temp_img_path)
447
  if not uploaded_url:
448
  return None, "original image upload failed"
449
 
@@ -454,7 +468,7 @@ def process_local_image_edit(base_image, layers, prompt, progress_callback=None)
454
  if progress_callback:
455
  progress_callback("uploading mask image...")
456
 
457
- # 上传mask图片
458
  mask_url = upload_mask_image_r2(client_ip, time_id, mask_image)
459
  if not mask_url:
460
  return None, "mask image upload failed"
@@ -507,18 +521,6 @@ def process_local_image_edit(base_image, layers, prompt, progress_callback=None)
507
  except Exception as e:
508
  print(f"❌ 局部编辑处理异常: {str(e)}")
509
  return None, f"error occurred during processing: {str(e)}"
510
-
511
- finally:
512
- # 清理临时文件
513
- if temp_img_path and os.path.exists(temp_img_path):
514
- try:
515
- os.remove(temp_img_path)
516
- temp_dir = os.path.dirname(temp_img_path)
517
- if os.path.exists(temp_dir):
518
- os.rmdir(temp_dir)
519
- print(f"🗑️ Cleaned up temporary file: {temp_img_path}")
520
- except Exception as cleanup_error:
521
- print(f"⚠️ Failed to clean up temporary file: {cleanup_error}")
522
 
523
 
524
  if __name__ == "__main__":
 
12
  import gradio as gr
13
  import boto3
14
  import tempfile
15
+ import io
16
  from botocore.client import Config
17
  from PIL import Image
18
 
 
32
  R2_ENDPOINT = OneKey[6]
33
 
34
 
35
+ # tmpFolder is no longer needed since we upload directly from memory
36
+ # tmpFolder = "tmp"
37
+ # os.makedirs(tmpFolder, exist_ok=True)
38
+
39
+
40
+ # Legacy function - no longer used since we upload directly from memory
41
+ # def upload_user_img(clientIp, timeId, img):
42
+ # fileName = clientIp.replace(".", "")+str(timeId)+".jpg"
43
+ # local_path = os.path.join(tmpFolder, fileName)
44
+ # img = cv2.imread(img)
45
+ # cv2.imwrite(os.path.join(tmpFolder, fileName), img)
46
+ #
47
+ # json_data = {
48
+ # "token": TOKEN,
49
+ # "input1": fileName,
50
+ # "input2": "",
51
+ # "protocol": "",
52
+ # "cloud": "ali"
53
+ # }
54
+ #
55
+ # session = requests.session()
56
+ # ret = requests.post(
57
+ # f"{UKAPIURL}/upload",
58
+ # headers={'Content-Type': 'application/json'},
59
+ # json=json_data
60
+ # )
61
+ #
62
+ # res = ""
63
+ # if ret.status_code==200:
64
+ # if 'upload1' in ret.json():
65
+ # upload_url = ret.json()['upload1']
66
+ # headers = {'Content-Type': 'image/jpeg'}
67
+ # response = session.put(upload_url, data=open(local_path, 'rb').read(), headers=headers)
68
+ # # print(response.status_code)
69
+ # if response.status_code == 200:
70
+ # res = upload_url
71
+ # if os.path.exists(local_path):
72
+ # os.remove(local_path)
73
+ # return res
74
 
75
 
76
  class R2Api:
 
93
 
94
  self.session = requests.Session() if session is None else session
95
 
96
+ def upload_from_memory(self, image_data, filename, content_type='image/jpeg'):
97
+ """
98
+ Upload image data directly from memory to R2
99
+
100
+ Args:
101
+ image_data (bytes): Image data in bytes
102
+ filename (str): Filename for the uploaded file
103
+ content_type (str): MIME type of the image
104
+
105
+ Returns:
106
+ str: URL of the uploaded file
107
+ """
108
+ t1 = time.time()
109
+ headers = {"Content-Type": content_type}
110
+
111
+ cloud_path = f"QwenImageEdit/Uploads/{str(datetime.date.today())}/{filename}"
112
+ url = self.client.generate_presigned_url(
113
+ "put_object",
114
+ Params={"Bucket": self.R2_BUCKET, "Key": cloud_path, "ContentType": content_type},
115
+ ExpiresIn=604800
116
+ )
117
+
118
+ retry_count = 0
119
+ while retry_count < 3:
120
+ try:
121
+ self.session.put(url, data=image_data, headers=headers, timeout=8)
122
+ break
123
+ except (requests.exceptions.Timeout, requests.exceptions.RequestException):
124
+ retry_count += 1
125
+ if retry_count == 3:
126
+ raise Exception('Failed to upload file to R2 after 3 retries!')
127
+ continue
128
+ print("upload_from_memory time is ====>", time.time() - t1)
129
+ return f"{self.domain}{cloud_path}"
130
+
131
  def upload_file(self, local_path, cloud_path):
132
  t1 = time.time()
133
  head_dict = {
 
165
  print("upload_file time is ====>", time.time() - t1)
166
  return f"{self.domain}{cloud_path}"
167
 
168
+ def upload_user_img_r2(clientIp, timeId, pil_image):
169
+ """
170
+ Upload PIL Image directly to R2 without saving to local file
171
+
172
+ Args:
173
+ clientIp (str): Client IP address
174
+ timeId (int): Timestamp
175
+ pil_image (PIL.Image): PIL Image object
176
+
177
+ Returns:
178
+ str: Uploaded URL
179
+ """
180
  fileName = clientIp.replace(".", "")+str(timeId)+".jpg"
181
+
182
+ # Convert PIL Image to bytes
183
+ img_buffer = io.BytesIO()
184
+ if pil_image.mode != 'RGB':
185
+ pil_image = pil_image.convert('RGB')
186
+ pil_image.save(img_buffer, format='JPEG', quality=95)
187
+ img_data = img_buffer.getvalue()
188
+
189
+ # Upload directly from memory
190
+ res = R2Api().upload_from_memory(img_data, fileName, 'image/jpeg')
191
  return res
192
 
193
 
 
254
 
255
  def upload_mask_image_r2(client_ip, time_id, mask_image):
256
  """
257
+ Upload mask image to R2 directly from memory
258
 
259
  Args:
260
  client_ip (str): Client IP
 
265
  str: Uploaded URL
266
  """
267
  file_name = f"{client_ip.replace('.', '')}{time_id}_mask.png"
 
268
 
269
  try:
270
+ # Convert mask image to bytes
271
+ img_buffer = io.BytesIO()
272
+ mask_image.save(img_buffer, format='PNG')
273
+ img_data = img_buffer.getvalue()
274
 
275
+ # Upload directly from memory
276
+ res = R2Api().upload_from_memory(img_data, file_name, 'image/png')
277
 
278
  return res
279
  except Exception as e:
280
  print(f"Failed to upload mask image: {e}")
281
  return None
 
 
 
 
282
 
283
 
284
 
 
361
  prompt: Editing instructions
362
  progress_callback: Progress callback function
363
  """
 
364
  try:
365
  # Generate client IP and timestamp
366
  client_ip = "127.0.0.1" # Default IP
 
368
 
369
  # Process input image - supports PIL Image and file path
370
  if hasattr(img_input, 'save'): # PIL Image object
371
+ pil_image = img_input
372
+ print(f"💾 Using PIL Image directly from memory")
 
 
 
 
 
 
 
 
 
373
  else:
374
+ # Load from file path
375
+ pil_image = Image.open(img_input)
376
+ print(f"📁 Loaded image from file: {img_input}")
377
 
378
  if progress_callback:
379
  progress_callback("uploading image...")
380
 
381
+ # Upload user image directly from memory
382
+ uploaded_url = upload_user_img_r2(client_ip, time_id, pil_image)
383
  if not uploaded_url:
384
  return None, "image upload failed"
385
 
 
413
  elif status in ['queued', 'processing', 'running', 'created', 'working']:
414
  if progress_callback:
415
  progress_callback(f"task processing... (status: {status})")
416
+ time.sleep(1)
417
  else:
418
  if progress_callback:
419
  progress_callback(f"unknown status: {status}")
 
423
 
424
  except Exception as e:
425
  return None, f"error occurred during processing: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
426
 
427
 
428
  def process_local_image_edit(base_image, layers, prompt, progress_callback=None):
 
435
  prompt (str): 编辑指令
436
  progress_callback: 进度回调函数
437
  """
 
 
 
438
  try:
439
  # Generate client IP and timestamp
440
  client_ip = "127.0.0.1" # Default IP
 
456
  if progress_callback:
457
  progress_callback("uploading original image...")
458
 
459
+ # 直接从内存上传原始图片
460
+ uploaded_url = upload_user_img_r2(client_ip, time_id, base_image)
 
 
 
 
 
 
 
 
 
461
  if not uploaded_url:
462
  return None, "original image upload failed"
463
 
 
468
  if progress_callback:
469
  progress_callback("uploading mask image...")
470
 
471
+ # 直接从内存上传mask图片
472
  mask_url = upload_mask_image_r2(client_ip, time_id, mask_image)
473
  if not mask_url:
474
  return None, "mask image upload failed"
 
521
  except Exception as e:
522
  print(f"❌ 局部编辑处理异常: {str(e)}")
523
  return None, f"error occurred during processing: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
524
 
525
 
526
  if __name__ == "__main__":