Deadmon commited on
Commit
bc35cc2
·
verified ·
1 Parent(s): e32837d

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +223 -0
app.py ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # App code based on: https://github.com/petergro-hub/ComicInpainting
2
+ # Model based on: https://github.com/saic-mdal/lama
3
+
4
+ import numpy as np
5
+ import pandas as pd
6
+ import streamlit as st
7
+ import os
8
+ from datetime import datetime
9
+ from PIL import Image
10
+ from streamlit_drawable_canvas import st_canvas
11
+ from io import BytesIO
12
+ from copy import deepcopy
13
+
14
+ from src.core import process_inpaint
15
+
16
+
17
+ def image_download_button(pil_image, filename: str, fmt: str, label="Download"):
18
+ if fmt not in ["jpg", "png"]:
19
+ raise Exception(f"Unknown image format (Available: {fmt} - case sensitive)")
20
+
21
+ pil_format = "JPEG" if fmt == "jpg" else "PNG"
22
+ file_format = "jpg" if fmt == "jpg" else "png"
23
+ mime = "image/jpeg" if fmt == "jpg" else "image/png"
24
+
25
+ buf = BytesIO()
26
+ pil_image.save(buf, format=pil_format)
27
+
28
+ return st.download_button(
29
+ label=label,
30
+ data=buf.getvalue(),
31
+ file_name=f'{filename}.{file_format}',
32
+ mime=mime,
33
+ )
34
+
35
+
36
+
37
+ if "button_id" not in st.session_state:
38
+ st.session_state["button_id"] = ""
39
+ if "color_to_label" not in st.session_state:
40
+ st.session_state["color_to_label"] = {}
41
+
42
+ if 'reuse_image' not in st.session_state:
43
+ st.session_state.reuse_image = None
44
+ def set_image(img):
45
+ st.session_state.reuse_image = img
46
+
47
+ st.title("AI Photo Object Removal")
48
+
49
+ st.image(open("assets/demo.png", "rb").read())
50
+
51
+ st.markdown(
52
+ """
53
+ So you want to remove an object in your photo? You don't need to learn photo editing skills.
54
+ **Just draw over the parts of the image you want to remove, then our AI will remove them.**
55
+ """
56
+ )
57
+ uploaded_file = st.file_uploader("Choose image", accept_multiple_files=False, type=["png", "jpg", "jpeg"])
58
+
59
+ if uploaded_file is not None:
60
+
61
+ if st.session_state.reuse_image is not None:
62
+ img_input = Image.fromarray(st.session_state.reuse_image)
63
+ else:
64
+ bytes_data = uploaded_file.getvalue()
65
+ img_input = Image.open(BytesIO(bytes_data)).convert("RGBA")
66
+
67
+ # Resize the image while maintaining aspect ratio
68
+ max_size = 2000
69
+ img_width, img_height = img_input.size
70
+ if img_width > max_size or img_height > max_size:
71
+ if img_width > img_height:
72
+ new_width = max_size
73
+ new_height = int((max_size / img_width) * img_height)
74
+ else:
75
+ new_height = max_size
76
+ new_width = int((max_size / img_height) * img_width)
77
+ img_input = img_input.resize((new_width, new_height))
78
+
79
+ stroke_width = st.slider("Brush size", 1, 100, 50)
80
+
81
+ st.write("**Now draw (brush) the part of image that you want to remove.**")
82
+
83
+ # Canvas size logic
84
+ canvas_bg = deepcopy(img_input)
85
+ aspect_ratio = canvas_bg.width / canvas_bg.height
86
+ streamlit_width = 720
87
+
88
+ # Max width is 720. Resize the height to maintain its aspectratio.
89
+ if canvas_bg.width > streamlit_width:
90
+ canvas_bg = canvas_bg.resize((streamlit_width, int(streamlit_width / aspect_ratio)))
91
+
92
+ canvas_result = st_canvas(
93
+ stroke_color="rgba(255, 0, 255, 1)",
94
+ stroke_width=stroke_width,
95
+ background_image=canvas_bg,
96
+ width=canvas_bg.width,
97
+ height=canvas_bg.height,
98
+ drawing_mode="freedraw",
99
+ key="compute_arc_length",
100
+ )
101
+
102
+ if canvas_result.image_data is not None:
103
+ im = np.array(Image.fromarray(canvas_result.image_data.astype(np.uint8)).resize(img_input.size))
104
+ background = np.where(
105
+ (im[:, :, 0] == 0) &
106
+ (im[:, :, 1] == 0) &
107
+ (im[:, :, 2] == 0)
108
+ )
109
+ drawing = np.where(
110
+ (im[:, :, 0] == 255) &
111
+ (im[:, :, 1] == 0) &
112
+ (im[:, :, 2] == 255)
113
+ )
114
+ im[background]=[0,0,0,255]
115
+ im[drawing]=[0,0,0,0] # RGBA
116
+
117
+ reuse = False
118
+
119
+ if st.button('Submit'):
120
+
121
+ with st.spinner("AI is doing the magic!"):
122
+ output = process_inpaint(np.array(img_input), np.array(im)) #TODO Put button here
123
+ img_output = Image.fromarray(output).convert("RGB")
124
+
125
+ st.write("AI has finished the job!")
126
+ st.image(img_output)
127
+ # reuse = st.button('Edit again (Re-use this image)', on_click=set_image, args=(inpainted_img, ))
128
+
129
+ uploaded_name = os.path.splitext(uploaded_file.name)[0]
130
+ image_download_button(
131
+ pil_image=img_output,
132
+ filename=uploaded_name,
133
+ fmt="jpg",
134
+ label="Download Image"
135
+ )
136
+
137
+ st.info("**TIP**: If the result is not perfect, you can download it then "
138
+ "upload then remove the artifacts.")
139
+
140
+
141
+ <style>
142
+ body {
143
+ font-family: 'Arial', sans-serif;
144
+ margin: 0;
145
+ background-color: #1a1a2e;
146
+ color: #ffffff;
147
+ overflow-x: hidden;
148
+ }
149
+
150
+ .stButton button {
151
+ background-color: #ffffff;
152
+ color: #1a1a2e;
153
+ }
154
+
155
+ .stButton button:hover {
156
+ background-color: #9370db;
157
+ color: #ffffff;
158
+ }
159
+
160
+ .stSlider {
161
+ color: #ffffff;
162
+ }
163
+
164
+ .stSlider .stSlider-label {
165
+ color: #ffffff;
166
+ }
167
+
168
+ .stSlider .stSlider-track {
169
+ background-color: #4a4a5e;
170
+ }
171
+
172
+ .stSlider .stSlider-thumb {
173
+ background-color: #ffffff;
174
+ }
175
+
176
+ .stMarkdown {
177
+ color: #ffffff;
178
+ }
179
+
180
+ .stSpinner {
181
+ color: #ffffff;
182
+ }
183
+
184
+ .stFileUploader {
185
+ background-color: #2a2a3e;
186
+ color: #ffffff;
187
+ border-color: #4a4a5e;
188
+ }
189
+
190
+ .stFileUploader:hover {
191
+ background-color: #3a3a4e;
192
+ }
193
+
194
+ .stImage {
195
+ max-width: 100%;
196
+ height: auto;
197
+ }
198
+
199
+ .stTextInput input {
200
+ background-color: #2a2a3e;
201
+ color: #ffffff;
202
+ border-color: #4a4a5e;
203
+ }
204
+
205
+ .stTextInput input:focus {
206
+ border-color: #6a6a7e;
207
+ }
208
+
209
+ .stDownloadButton {
210
+ background-color: #ffffff;
211
+ color: #1a1a2e;
212
+ }
213
+
214
+ .stDownloadButton:hover {
215
+ background-color: #9370db;
216
+ color: #ffffff;
217
+ }
218
+
219
+ .stInfo {
220
+ background-color: #2a2a3e;
221
+ color: #ffffff;
222
+ }
223
+ </style>