AItool commited on
Commit
930e203
·
verified ·
1 Parent(s): dfb30fb

Create app.py

Browse files

It was deleted!!! now in again.

Files changed (1) hide show
  1. app.py +284 -0
app.py ADDED
@@ -0,0 +1,284 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, File, UploadFile, Form
2
+ from fastapi.responses import HTMLResponse
3
+ from fastapi.staticfiles import StaticFiles
4
+ import numpy as np
5
+ from PIL import Image
6
+ from io import BytesIO
7
+ import requests
8
+ import base64
9
+ import os
10
+ from tkinter import Tk, Label, Button, Radiobutton, IntVar
11
+
12
+ app = FastAPI()
13
+
14
+ # Mount the static folder for CSS and other assets
15
+ app.mount("/static", StaticFiles(directory="static"), name="static")
16
+
17
+ # Function to add padding
18
+ def fill_rectangle_cropper(img, padding_type):
19
+ # Calculate the average color of the image
20
+ avg_color_per_row = np.average(np.array(img), axis=0)
21
+ avg_color = np.average(avg_color_per_row, axis=0)
22
+
23
+ if padding_type == "top_bottom":
24
+ # Increase height to create a rectangle
25
+ new_height = int(img.width * (4/3)) # Example: height = width * 4/3
26
+ newimg = Image.new(
27
+ 'RGB',
28
+ (img.width, new_height),
29
+ (round(avg_color[0]), round(avg_color[1]), round(avg_color[2]))
30
+ )
31
+ padding_top = (new_height - img.height) // 2
32
+ newimg.paste(img, (0, padding_top)) # Center the image vertically
33
+ return newimg
34
+
35
+ elif padding_type == "left_right":
36
+ # Increase width to create a rectangle
37
+ new_width = int(img.height * (4/3)) # Example: width = height * 4/3
38
+ newimg = Image.new(
39
+ 'RGB',
40
+ (new_width, img.height),
41
+ (round(avg_color[0]), round(avg_color[1]), round(avg_color[2]))
42
+ )
43
+ padding_left = (new_width - img.width) // 2
44
+ newimg.paste(img, (padding_left, 0)) # Center the image horizontally
45
+ return newimg
46
+
47
+ # Function for cropping and filling the image
48
+ def fill_rectangle_cropper1(img):
49
+ imgsz = [img.height, img.width]
50
+ avg_color_per_row = np.average(img, axis=0)
51
+ avg_color = np.average(avg_color_per_row, axis=0)
52
+
53
+ if img.height > img.width:
54
+ newimg = Image.new(
55
+ 'RGB',
56
+ (img.height, img.height),
57
+ (round(avg_color[0]), round(avg_color[1]), round(avg_color[2]))
58
+ )
59
+ newpos = (img.height - img.width) // 2
60
+
61
+
62
+ newimg.paste(img, (newpos, 0))
63
+ return newimg
64
+
65
+ elif img.width > img.height:
66
+ newimg = Image.new(
67
+ 'RGB',
68
+ (img.width, img.width),
69
+ (round(avg_color[0]), round(avg_color[1]), round(avg_color[2]))
70
+ )
71
+ newpos = (img.width - img.height) // 2
72
+ newimg.paste(img, (0, newpos))
73
+ return newimg
74
+ else:
75
+ return img
76
+
77
+
78
+ # Home Page
79
+ @app.get("/", response_class=HTMLResponse)
80
+ def home_page():
81
+ return """
82
+ <html>
83
+ <head>
84
+ <title>Part of Idoia's Developer Portfolio - Innovating the Web</title>
85
+ <link rel="stylesheet" href="/static/styles/style.css">
86
+
87
+ <!-- Meta Tags for SEO -->
88
+ <meta charset="UTF-8">
89
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
90
+ <meta name="description" content="Explore the developer portfolio of Idoia, showcasing expertise in FastAPI, web development, and cutting-edge applications.">
91
+ <meta name="keywords" content="Idoia, Developer, FastAPI, Web Development, Python Projects, Image Processing, Online Portfolio">
92
+ <meta name="author" content="Idoia">
93
+
94
+ <!-- Open Graph Meta Tags -->
95
+ <meta property="og:title" content="Idoia's Developer Portfolio - Innovating the Web">
96
+ <meta property="og:description" content="Showcasing FastAPI projects, web apps, and image processing expertise. Explore Idoia's developer journey.">
97
+ <meta property="og:image" content="/static/images/banner.jpg">
98
+ <meta property="og:url" content="https://webdevserv.github.io/html_bites/dev/webdev.html">
99
+ <meta property="og:type" content="website">
100
+
101
+ <!-- Twitter Card Meta Tags -->
102
+ <meta name="twitter:card" content="summary_large_image">
103
+ <meta name="twitter:title" content="Idoia's Developer Portfolio - Innovating the Web">
104
+ <meta name="twitter:description" content="Discover the developer profile of Idoia. Dive into FastAPI-powered web apps and creative Python projects.">
105
+ <meta name="twitter:image" content="/static/images/banner.jpg">
106
+ <link rel="icon" href="/static/images/6464.ico" type="image/x-icon">
107
+
108
+ <!-- Google Fonts (Optional for Styling) -->
109
+ <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet">
110
+
111
+ <!-- Schema.org JSON-LD (Optional for Rich Snippets) -->
112
+ <script type="application/ld+json">
113
+ {
114
+ "@context": "https://schema.org",
115
+ "@type": "Person",
116
+ "name": "Idoia",
117
+ "jobTitle": "Web Developer",
118
+ "url": "https://webdevserv.github.io/html_bites/dev/webdev.html",
119
+ "image": "https://idoia-dev-portfolio.com/static/images/banner.jpg",
120
+ "description": "Experienced web developer with a focus on Streamlit, HF, Python, and modern web applications."
121
+ }
122
+ </script>
123
+ </head>
124
+ <body>
125
+ <img class="banner" src="/static/images/banner.jpg" alt="Banner" width="100%">
126
+ <h2>Rectangle and Fill Image App</h2>
127
+ <p>Please select an option below:</p>
128
+ <ul>
129
+ <li><a href="/demo">Demo</a></li>
130
+ <li><a href="/application">Application</a></li>
131
+ </ul>
132
+ <div id="credit">Image creations by
133
+ <a href="https://stock.adobe.com/es/contributor/212598146/UMAMI%20LAB" target="_blank">Adobe Stock User Umami Lab</a>
134
+ and
135
+ <a href="https://www.shutterstock.com/g/Idoia+Lerchundi?rid=430751957" target="_blank">Shutterstock User PhoArt101</a>.
136
+ </div>
137
+ </body>
138
+ </html>
139
+ """
140
+
141
+ # Demo Page
142
+ @app.get("/demo", response_class=HTMLResponse)
143
+ def demo_page():
144
+ # URLs for demo images
145
+ url1 = "https://raw.githubusercontent.com/webdevserv/images_video/main/squareportrait.png"
146
+ url2 = "https://raw.githubusercontent.com/webdevserv/images_video/main/squarelandscape.png"
147
+
148
+ # Process the first image
149
+ response = requests.get(url1)
150
+ img1 = Image.open(BytesIO(response.content)).convert("RGB")
151
+ rectangled_img1 = fill_rectangle_cropper(img1, "top_bottom")
152
+ output1 = BytesIO()
153
+ rectangled_img1.save(output1, format="JPEG")
154
+ encoded_img1 = base64.b64encode(output1.getvalue()).decode("utf-8")
155
+
156
+ # Process the second image
157
+ response = requests.get(url2)
158
+ img2 = Image.open(BytesIO(response.content)).convert("RGB")
159
+ rectangled_img2 = fill_rectangle_cropper(img2, "left_right")
160
+ output2 = BytesIO()
161
+ rectangled_img2.save(output2, format="JPEG")
162
+ encoded_img2 = base64.b64encode(output2.getvalue()).decode("utf-8")
163
+
164
+ return f"""
165
+ <html>
166
+ <head>
167
+ <title>Part of Idoia's Developer Portfolio - Innovating the Web</title>
168
+ <link rel="stylesheet" href="/static/styles/style.css">
169
+ </head>
170
+ <body>
171
+ <img class="banner" src="/static/images/banner.jpg" alt="Banner" width="100%">
172
+ <h2>Rectangle Image Demo</h2>
173
+ <p>Image will be rectangled with color filler where applicable.</p>
174
+ <h3>Result 1:</h3>
175
+ <img src="data:image/jpeg;base64,{encoded_img1}" />
176
+ <h3>Result 2:</h3>
177
+ <img src="data:image/jpeg;base64,{encoded_img2}" />
178
+ <p><a href="/">Back</a></p>
179
+ <div id="credit">Image creations by
180
+ <a href="https://stock.adobe.com/es/contributor/212598146/UMAMI%20LAB" target="_blank">Adobe Stock User Umami Lab</a>
181
+ and
182
+ <a href="https://www.shutterstock.com/g/Idoia+Lerchundi?rid=430751957" target="_blank">Shutterstock User PhoArt101</a>.
183
+ </div>
184
+ </body>
185
+ </html>
186
+ """
187
+
188
+ # Application Page
189
+ @app.get("/application", response_class=HTMLResponse)
190
+ def application_page():
191
+ return """
192
+ <html>
193
+ <head>
194
+ <title>Part of Idoia's Developer Portfolio - Innovating the Web</title>
195
+ <link rel="stylesheet" href="/static/styles/style.css">
196
+ </head>
197
+ <body>
198
+ <img class="banner" src="/static/images/banner.jpg" alt="Banner" width="100%">
199
+ <h2>Rectangle Image Application</h2>
200
+ <p>Upload a JPG image to rectangle and fill with color filler.</p>
201
+ <form action="/upload/" enctype="multipart/form-data" method="post">
202
+ <label for="file">Upload your image:</label>
203
+ <input name="file" type="file" required><br><br>
204
+
205
+ <label>Choose the padding direction:</label><br>
206
+ <input type="radio" id="top_bottom" name="padding_type" value="top_bottom" checked>
207
+ <label for="top_bottom">Top/Bottom</label><br>
208
+ <input type="radio" id="left_right" name="padding_type" value="left_right">
209
+ <label for="left_right">Left/Right</label><br><br>
210
+
211
+ <input type="submit" value="Rectangle It">
212
+ </form>
213
+ <a href="/">Back</a>
214
+ <div id="credit">Image creations by
215
+ <a href="https://stock.adobe.com/es/contributor/212598146/UMAMI%20LAB" target="_blank">Adobe Stock User Umami Lab</a>
216
+ and
217
+ <a href="https://www.shutterstock.com/g/Idoia+Lerchundi?rid=430751957" target="_blank">Shutterstock User PhoArt101</a>.
218
+ </div>
219
+ </body>
220
+ </html>
221
+ """
222
+
223
+ @app.post("/upload/")
224
+ async def upload_file(file: UploadFile = File(...), padding_type: str = Form(...)):
225
+ try:
226
+ # Await file upload
227
+ contents = await file.read()
228
+ img = Image.open(BytesIO(contents)).convert("RGB")
229
+ # Apply padding based on user's choice
230
+ rectangled_img = fill_rectangle_cropper(img,padding_type)
231
+
232
+ # Save the rectangle image (original size)
233
+ output = BytesIO()
234
+ rectangled_img.save(output, format="JPEG")
235
+ output.seek(0)
236
+
237
+ # Encode the full-size image for download
238
+ full_size_encoded_img = base64.b64encode(output.getvalue()).decode("utf-8")
239
+
240
+ # Resize the image for display (512px by 512px)
241
+ display_img = rectangled_img.copy()
242
+ desired_width = 512
243
+ aspect_ratio = display_img.height / display_img.width
244
+ desired_height = int(desired_width * aspect_ratio)
245
+ display_img.thumbnail((desired_width, desired_height))
246
+ display_output = BytesIO()
247
+ display_img.save(display_output, format="JPEG")
248
+ display_output.seek(0)
249
+
250
+ # Encode the resized display image
251
+ display_encoded_img = base64.b64encode(display_output.getvalue()).decode("utf-8")
252
+
253
+ # Return the HTML response
254
+ return HTMLResponse(
255
+ content=f"""
256
+ <html>
257
+ <head>
258
+ <title>Part of Idoia's Developer Portfolio - Innovating the Web</title>
259
+ <link rel="stylesheet" href="/static/styles/style.css">
260
+ </head>
261
+ <body>
262
+ <img class="banner" src="/static/images/banner.jpg" alt="Banner" width="100%">
263
+ <h2>Image successfully rectangled!</h2>
264
+ <!--<img src='data:image/jpeg;base64,display_encoded_img'/>-->
265
+ <img src='data:image/jpeg;base64,{display_encoded_img}' width="512"/>
266
+ <p><a href="data:image/jpeg;base64,{full_size_encoded_img}" download="rectangled_image.jpg">
267
+ Download Full-Size Image</a></p>
268
+ <p><a href="/">Back</a></p>
269
+ <div id="credit">Image creations by
270
+ <a href="https://stock.adobe.com/es/contributor/212598146/UMAMI%20LAB" target="_blank">Adobe Stock User Umami Lab</a>
271
+ and
272
+ <a href="https://www.shutterstock.com/g/Idoia+Lerchundi?rid=430751957" target="_blank">Shutterstock User PhoArt101</a>.
273
+ </div>
274
+ </body>
275
+ </html>
276
+ """,
277
+ media_type="text/html"
278
+ )
279
+ except Exception as e:
280
+ return HTMLResponse(content=f"<h3>An error occurred: {e}</h3>", media_type="text/html")
281
+
282
+ if __name__ == "__main__":
283
+ import uvicorn
284
+ uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("PORT", 7860)))