uyen22 commited on
Commit
731d309
·
verified ·
1 Parent(s): 42d612e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +109 -66
app.py CHANGED
@@ -1,74 +1,117 @@
1
- import gradio as gr
 
2
  import requests
3
- from PIL import Image, ImageOps
4
  from io import BytesIO
5
- import numpy as np
6
 
7
- # Hàm xử lý gửi ảnh và mask tới API Magic Studio
8
- def process_inpaint_via_api(image, mask):
9
- url = "https://api.magicstudio.com/magiceraser/erase"
10
-
11
- headers = {
12
- 'accessToken': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjbGllbnRfaWQiOiIyRGZQSm1sY1BLalBuaGh4ajBxSVpmQktfbS12RFhTc1NMRFNOX1gtZlVVIiwiZXhwIjoxNzI3MTY0MTcyLCJhcHBfbmFtZSI6IjE3NTMwODQiLCJtZXRhbnRfdHlwZSI6ImNyZWQifQ.24oHGH9ial_gqeYrpUbYP68MwYly2ArzXbhbE1hGzQo'
13
- }
14
-
15
- # Chuyển đổi ảnh và mask thành định dạng PNG để gửi tới API
16
- image_io = BytesIO()
17
- mask_io = BytesIO()
18
-
19
- image.save(image_io, format="PNG")
20
- mask.save(mask_io, format="PNG")
21
-
22
- image_io.seek(0)
23
- mask_io.seek(0)
24
-
25
- files = [
26
- ('image_file', ('image.png', image_io, 'image/png')),
27
- ('mask_file', ('mask.png', mask_io, 'image/png'))
28
- ]
29
-
30
- # Gửi yêu cầu POST tới API
31
- response = requests.post(url, headers=headers, files=files)
32
-
33
- if response.status_code == 200:
34
- # Nếu API trả về thành công, xử lý và trả về ảnh kết quả
35
- return Image.open(BytesIO(response.content))
36
- else:
37
- # Nếu có lỗi, hiển thị lỗi
38
- return f"API Error: {response.status_code} - {response.text}"
39
-
40
- # Hàm xử lý kết hợp ảnh và mask
41
- def process(image, mask):
42
- img = Image.fromarray(image).convert("RGBA")
43
-
44
- # Mask nhận được từ Image Sketchpad dưới dạng ảnh RGBA, cần chuyển sang ảnh nhị phân
45
- mask = Image.fromarray(mask).convert("L")
46
- mask = ImageOps.invert(mask) # Invert lại mask để đảo ngược vùng vẽ
47
-
48
- # Gọi API với ảnh và mask
49
- result = process_inpaint_via_api(img, mask)
50
 
51
- # Nếu kết quả trả về là lỗi, hiển thị thông báo
52
- if isinstance(result, str):
53
- return None, result
54
 
55
- # Trả về ảnh đã xử lý
56
- return result, "Processing complete."
 
 
 
 
57
 
58
- # Tạo giao diện Gradio
59
- with gr.Blocks() as demo:
60
- gr.Markdown("# AI Object Removal using Magic Studio API")
61
-
62
- # Tải ảnh lên từ người dùng và cho phép vẽ mask đè trực tiếp lên ảnh đã tải lên
63
- image_input = gr.Image(type="numpy", tool="sketch", label="Upload an image and draw mask")
64
 
65
- # Khu vực hiển thị kết quả
66
- result_output = gr.Image(label="Output Image")
67
- output_message = gr.Textbox(label="Message", lines=2)
68
-
69
- # Nút xử và kết nối các thành phần với hàm process
70
- process_button = gr.Button("Submit")
71
- process_button.click(process, inputs=[image_input, image_input], outputs=[result_output, output_message])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
- # Khởi chạy ứng dụng Gradio
74
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import streamlit as st
3
  import requests
4
+ from PIL import Image
5
  from io import BytesIO
6
+ from streamlit_drawable_canvas import st_canvas
7
 
8
+ # API information
9
+ url = "https://api.magicstudio.com/magiceraser/erase"
10
+ access_token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjbGllbnRfaWQiOiIyRGZQSm1sY1BLalBuaGh4ajBxSVpmQktfbS12RFhTc1NMRFNOX1gtZlVVIiwiZXhwIjoxNzI3MTY0MTcyLCJhcHBfbmFtZSI6IjE3NTMwODQiLCJtZXRhZGF0YSI6bnVsbCwiZ3JhbnRfdHlwZSI6ImNyZWQifQ.24oHGH9ial_gqeYrpUbYP68MwYly2ArzXbhbE1hGzQo' # Your actual token
11
+
12
+ def image_download_button(pil_image, filename: str, fmt: str, label="Download"):
13
+ pil_format = "JPEG" if fmt == "jpg" else "PNG"
14
+ file_format = "jpg" if fmt == "jpg" else "png"
15
+ mime = "image/jpeg" if fmt == "jpg" else "image/png"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
+ buf = BytesIO()
18
+ pil_image.save(buf, format=pil_format)
 
19
 
20
+ return st.download_button(
21
+ label=label,
22
+ data=buf.getvalue(),
23
+ file_name=f'{filename}.{file_format}',
24
+ mime=mime,
25
+ )
26
 
27
+ # Set title of the app
28
+ st.title("AI Photo Object Removal")
 
 
 
 
29
 
30
+ # Upload the image
31
+ uploaded_file = st.file_uploader("Upload an image to remove objects from", type=["png", "jpg", "jpeg"])
32
+
33
+ if uploaded_file is not None:
34
+ # Load the uploaded image
35
+ img_input = Image.open(uploaded_file).convert("RGBA")
36
+
37
+ # Resize image if too large
38
+ max_size = 2000
39
+ img_width, img_height = img_input.size
40
+ if img_width > max_size or img_height > max_size:
41
+ if img_width > img_height:
42
+ new_width = max_size
43
+ new_height = int((max_size / img_width) * img_height)
44
+ else:
45
+ new_height = max_size
46
+ new_width = int((max_size / img_height) * img_width)
47
+ img_input = img_input.resize((new_width, new_height))
48
+
49
+ # Display the image and let the user draw the mask
50
+ stroke_width = st.slider("Brush size", 1, 100, 50)
51
+ st.write("**Draw over the parts of the image you want to remove.**")
52
+
53
+ # Create a drawing canvas for the mask
54
+ canvas_result = st_canvas(
55
+ stroke_color="rgba(255, 0, 255, 1)", # Pink color for the brush
56
+ stroke_width=stroke_width,
57
+ background_image=img_input,
58
+ update_streamlit=True,
59
+ height=img_input.height,
60
+ width=img_input.width,
61
+ drawing_mode="freedraw",
62
+ key="canvas",
63
+ )
64
+
65
+ if canvas_result.image_data is not None:
66
+ # Convert the drawing into a mask
67
+ mask_image = Image.fromarray((canvas_result.image_data[:, :, 3] > 0).astype(int) * 255)
68
+ mask_image = mask_image.resize(img_input.size).convert("L") # Convert to grayscale
69
+
70
+ # Display the mask for the user to review
71
+ st.write("**Generated Mask:**")
72
+ st.image(mask_image)
73
+
74
+ if st.button('Submit'):
75
+ with st.spinner("AI is processing..."):
76
+ try:
77
+ # Convert both image and mask to binary format for API upload
78
+ img_buffer = BytesIO()
79
+ mask_buffer = BytesIO()
80
+
81
+ img_input.save(img_buffer, format='PNG')
82
+ mask_image.save(mask_buffer, format='PNG')
83
+
84
+ # Prepare the files for the API
85
+ files = [
86
+ ('image_file', ('image.png', img_buffer.getvalue(), 'image/png')),
87
+ ('mask_file', ('mask.png', mask_buffer.getvalue(), 'image/png')),
88
+ ]
89
+
90
+ headers = {
91
+ 'accessToken': access_token
92
+ }
93
+
94
+ # Send POST request to MagicEraser API
95
+ response = requests.post(url, headers=headers, files=files)
96
+
97
+ if response.status_code == 200:
98
+ # Process and display the result
99
+ result_image = Image.open(BytesIO(response.content)).convert("RGB")
100
+ st.write("AI has finished the job!")
101
+ st.image(result_image)
102
 
103
+ # Download button for the output image
104
+ uploaded_name = uploaded_file.name.split('.')[0]
105
+ image_download_button(
106
+ pil_image=result_image,
107
+ filename=f"{uploaded_name}_output",
108
+ fmt="jpg",
109
+ label="Download Image"
110
+ )
111
+ else:
112
+ st.error(f"Error: {response.status_code} - {response.text}")
113
+ except Exception as e:
114
+ st.error(f"Error processing the image: {e}")
115
+ if __name__ == "__main__":
116
+ import os
117
+ os.system("streamlit run app.py")