ALIMHGFY commited on
Commit
a7a6db0
·
verified ·
1 Parent(s): 1381628

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +52 -65
app.py CHANGED
@@ -1,95 +1,57 @@
1
  import gradio as gr
2
  import numpy as np
 
3
  import os
4
  from PIL import Image
5
  import requests
6
  from io import BytesIO
7
  import io
8
  import base64
9
- import json # لإضافة دعم قراءة ملف config.json
10
 
11
- # الحصول على التوكن من متغير البيئة
12
- hf_token = os.environ.get("HF_TOKEN_API_DEMO")
13
- if not hf_token:
14
- raise ValueError("HF_TOKEN_API_DEMO is not set. Please set it as an environment variable.")
15
  auth_headers = {"api_token": hf_token}
16
 
17
- # تحميل إعدادات النموذج من ملف config.json
18
- def load_config(config_path="config.json"):
19
- if not os.path.exists(config_path):
20
- raise FileNotFoundError(f"Config file not found at {config_path}")
21
- with open(config_path, 'r') as file:
22
- config = json.load(file)
23
- print("Config loaded successfully:", config)
24
- return config
25
-
26
- # تحويل الصورة إلى Base64
27
  def convert_mask_image_to_base64_string(mask_image):
28
  buffer = io.BytesIO()
29
- mask_image.save(buffer, format="PNG")
 
30
  image_base64_string = base64.b64encode(buffer.getvalue()).decode('utf-8')
31
- return f",{image_base64_string}"
32
 
33
- # تنزيل الصورة من رابط
34
  def download_image(url):
35
  response = requests.get(url)
36
- if response.status_code != 200:
37
- raise ValueError(f"Failed to download image from {url}. Status code: {response.status_code}")
38
  return Image.open(BytesIO(response.content)).convert("RGB")
39
 
40
- # استدعاء API الخاص بالإزالة
41
  def eraser_api_call(image_base64_file, mask_base64_file, mask_type):
 
42
  url = "http://engine.prod.bria-api.com/v1/eraser"
 
43
  payload = {
44
- "file": image_base64_file,
45
- "mask_file": mask_base64_file,
46
- "mask_type": mask_type,
47
  }
48
- print(f"Payload being sent: {payload}") # طباعة البيانات المرسلة
49
  response = requests.post(url, json=payload, headers=auth_headers)
50
- print(f"API Response Code: {response.status_code}") # طباعة رمز الاستجابة
51
- if response.status_code != 200:
52
- print(f"Error Response: {response.text}") # طباعة نص الخطأ إذا حدث
53
- raise ValueError(f"API request failed: {response.status_code}")
54
- try:
55
- response_json = response.json()
56
- print("Response JSON:", response_json) # طباعة الرد JSON
57
- except ValueError:
58
- raise ValueError("Invalid JSON response from API")
59
-
60
- if "result_url" not in response_json:
61
- raise KeyError("The key 'result_url' is missing in the response JSON")
62
 
63
- res_image = download_image(response_json["result_url"])
64
  return res_image
65
 
66
- # دالة التنبؤ
67
- def predict(dict):
68
- print("Predict function called.") # للتأكد من استدعاء الدالة
69
- print("Received Data Keys:", dict.keys()) # طباعة المفاتيح المستلمة
70
 
71
- if 'background' not in dict or 'layers' not in dict:
72
- raise ValueError("Invalid input format. Missing 'background' or 'layers' keys.")
73
 
74
- init_image = Image.fromarray(dict['background'][:, :, :3], 'RGB')
75
- mask = Image.fromarray(dict['layers'][0][:, :, 3], 'L')
76
 
77
- print("Initial image and mask created.") # تأكيد نجاح إنشاء الصور
78
-
79
  image_base64_file = convert_mask_image_to_base64_string(init_image)
80
  mask_base64_file = convert_mask_image_to_base64_string(mask)
81
 
82
  mask_type = "manual"
83
- print("Sending API call...") # تأكيد استدعاء API
84
  gen_img = eraser_api_call(image_base64_file, mask_base64_file, mask_type)
85
- print("API call completed.") # تأكيد انتهاء استدعاء API
86
 
87
  return gen_img
88
 
89
- # قراءة إعدادات config.json (إذا لزم الأمر)
90
- config = load_config()
91
 
92
- # CSS مخصص
93
  css = '''
94
  .gradio-container{max-width: 1100px !important}
95
  #image_upload{min-height:400px}
@@ -137,24 +99,49 @@ div#share-btn-container > div {flex-direction: row;background: black;align-items
137
  #image_upload{border-bottom-left-radius: 0px;border-bottom-right-radius: 0px}
138
  '''
139
 
140
- # واجهة Gradio
141
  image_blocks = gr.Blocks(css=css, elem_id="total-container")
142
  with image_blocks as demo:
143
  with gr.Column(elem_id="col-container"):
144
  gr.Markdown("## BRIA Eraser API")
145
- gr.HTML('''<p>Demo description here...</p>''')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
146
  with gr.Row():
147
  with gr.Column():
148
- image = gr.ImageEditor(
149
- sources=["upload"],
150
- layers=False,
151
- transforms=[],
152
- brush=gr.Brush(colors=["#000000"], color_mode="fixed")
153
- )
154
  with gr.Row(elem_id="prompt-container", equal_height=True):
155
- btn = gr.Button("Erase!", elem_id="run_button")
 
 
156
  with gr.Column():
157
  image_out = gr.Image(label="Output", elem_id="output-img")
158
- btn.click(fn=predict, inputs=image, outputs=image_out, api_name='run')
159
- gr.HTML("<div class='footer'><p>Footer text here...</p></div>")
160
- image_blocks.queue(max_size=25, api_open=False).launch(show_api=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import gradio as gr
2
  import numpy as np
3
+
4
  import os
5
  from PIL import Image
6
  import requests
7
  from io import BytesIO
8
  import io
9
  import base64
 
10
 
11
+ hf_token = os.environ.get("HF_TOKEN_API_DEMO") # we get it from a secret env variable, such that it's private
 
 
 
12
  auth_headers = {"api_token": hf_token}
13
 
 
 
 
 
 
 
 
 
 
 
14
  def convert_mask_image_to_base64_string(mask_image):
15
  buffer = io.BytesIO()
16
+ mask_image.save(buffer, format="PNG") # You can choose the format (e.g., "JPEG", "PNG")
17
+ # Encode the buffer in base64
18
  image_base64_string = base64.b64encode(buffer.getvalue()).decode('utf-8')
19
+ return f",{image_base64_string}" # for some reason the funciton which downloads image from base64 expects prefix of "," which is redundant in the url
20
 
 
21
  def download_image(url):
22
  response = requests.get(url)
 
 
23
  return Image.open(BytesIO(response.content)).convert("RGB")
24
 
 
25
  def eraser_api_call(image_base64_file, mask_base64_file, mask_type):
26
+
27
  url = "http://engine.prod.bria-api.com/v1/eraser"
28
+
29
  payload = {
30
+ "file": image_base64_file,
31
+ "mask_file": mask_base64_file,
32
+ "mask_type": mask_type,
33
  }
 
34
  response = requests.post(url, json=payload, headers=auth_headers)
35
+ response = response.json()
36
+ res_image = download_image(response["result_url"])
 
 
 
 
 
 
 
 
 
 
37
 
 
38
  return res_image
39
 
 
 
 
 
40
 
41
+ def predict(dict):
 
42
 
43
+ init_image = Image.fromarray(dict['background'][:, :, :3], 'RGB') #dict['background'].convert("RGB")#.resize((1024, 1024))
44
+ mask = Image.fromarray(dict['layers'][0][:,:,3], 'L') #dict['layers'].convert("RGB")#.resize((1024, 1024))
45
 
 
 
46
  image_base64_file = convert_mask_image_to_base64_string(init_image)
47
  mask_base64_file = convert_mask_image_to_base64_string(mask)
48
 
49
  mask_type = "manual"
 
50
  gen_img = eraser_api_call(image_base64_file, mask_base64_file, mask_type)
 
51
 
52
  return gen_img
53
 
 
 
54
 
 
55
  css = '''
56
  .gradio-container{max-width: 1100px !important}
57
  #image_upload{min-height:400px}
 
99
  #image_upload{border-bottom-left-radius: 0px;border-bottom-right-radius: 0px}
100
  '''
101
 
 
102
  image_blocks = gr.Blocks(css=css, elem_id="total-container")
103
  with image_blocks as demo:
104
  with gr.Column(elem_id="col-container"):
105
  gr.Markdown("## BRIA Eraser API")
106
+ gr.HTML('''
107
+ <p style="margin-bottom: 10px; font-size: 94%">
108
+ This demo showcases the BRIA Eraser capability, which allows users to remove specific elements or objects from images.<br>
109
+ The pipeline comprises multiple components, including <a href="https://huggingface.co/briaai/BRIA-2.3" target="_blank">briaai/BRIA-2.3</a>,
110
+ <a href="https://huggingface.co/briaai/BRIA-2.3-ControlNet-Inpainting" target="_blank">briaai/BRIA-2.3-ControlNet-Inpainting</a>,
111
+ and <a href="https://huggingface.co/briaai/BRIA-2.3-FAST-LORA" target="_blank">briaai/BRIA-2.3-FAST-LORA</a>, all trained on licensed data.<br>
112
+ This ensures full legal liability coverage for copyright and privacy infringement.<br>
113
+ Notes:<br>
114
+ - High-resolution images may take longer to process.<br>
115
+ - For multiple masks, results are better if all masks are included in inference.<br><br>
116
+ </p>
117
+ <p style="margin-bottom: 10px; font-size: 94%">
118
+ API Endpoint available on: <a href="https://fal.ai/models/fal-ai/bria/eraser" target="_blank">fal.ai</a><br>
119
+ ComfyUI node is available here: <a href="https://github.com/Bria-AI/ComfyUI-BRIA-API" target="_blank">ComfyUI Node</a>
120
+ </p>
121
+ ''')
122
  with gr.Row():
123
  with gr.Column():
124
+ image = gr.ImageEditor(sources=["upload"], layers=False, transforms=[],
125
+ brush=gr.Brush(colors=["#000000"], color_mode="fixed"),
126
+ )
 
 
 
127
  with gr.Row(elem_id="prompt-container", equal_height=True):
128
+ with gr.Column(): # Wrap the button inside a Column
129
+ btn = gr.Button("Erase!", elem_id="run_button")
130
+
131
  with gr.Column():
132
  image_out = gr.Image(label="Output", elem_id="output-img")
133
+
134
+ # Button click will trigger the inpainting function (no prompt required)
135
+ btn.click(fn=predict, inputs=[image], outputs=[image_out], api_name='run')
136
+
137
+
138
+ gr.HTML(
139
+ """
140
+ <div class="footer">
141
+ <p>Model by <a href="https://huggingface.co/diffusers" style="text-decoration: underline;" target="_blank">Diffusers</a> - Gradio Demo by 🤗 Hugging Face
142
+ </p>
143
+ </div>
144
+ """
145
+ )
146
+
147
+ image_blocks.queue(max_size=25,api_open=False).launch(show_api=False)