from fastapi import FastAPI, File, UploadFile, Form from fastapi.responses import HTMLResponse from fastapi.staticfiles import StaticFiles import numpy as np from PIL import Image from io import BytesIO import requests import base64 import os from tkinter import Tk, Label, Button, Radiobutton, IntVar app = FastAPI() # Mount the static folder for CSS and other assets app.mount("/static", StaticFiles(directory="static"), name="static") # Function to add padding def fill_rectangle_cropper(img, padding_type): # Calculate the average color of the image avg_color_per_row = np.average(np.array(img), axis=0) avg_color = np.average(avg_color_per_row, axis=0) if padding_type == "top_bottom": # Increase height to create a rectangle new_height = int(img.width * (4/3)) # Example: height = width * 4/3 newimg = Image.new( 'RGB', (img.width, new_height), (round(avg_color[0]), round(avg_color[1]), round(avg_color[2])) ) padding_top = (new_height - img.height) // 2 newimg.paste(img, (0, padding_top)) # Center the image vertically return newimg elif padding_type == "left_right": # Increase width to create a rectangle new_width = int(img.height * (4/3)) # Example: width = height * 4/3 newimg = Image.new( 'RGB', (new_width, img.height), (round(avg_color[0]), round(avg_color[1]), round(avg_color[2])) ) padding_left = (new_width - img.width) // 2 newimg.paste(img, (padding_left, 0)) # Center the image horizontally return newimg # Home Page @app.get("/", response_class=HTMLResponse) def home_page(): return """ Part of Idoia's Developer Portfolio - Innovating the Web

Rectangle and Fill Image App

Please select an option below:

Image credit Adobe Stock User Umami Lab and Shutterstock User PhoArt101.
""" # Demo Page @app.get("/demo", response_class=HTMLResponse) def demo_page(): # URLs for demo images url1 = "https://raw.githubusercontent.com/webdevserv/images_video/main/squareportrait.png" url2 = "https://raw.githubusercontent.com/webdevserv/images_video/main/squarelandscape.png" # Process the first image response = requests.get(url1) img1 = Image.open(BytesIO(response.content)).convert("RGB") rectangled_img1 = fill_rectangle_cropper(img1, "top_bottom") output1 = BytesIO() rectangled_img1.save(output1, format="JPEG") encoded_img1 = base64.b64encode(output1.getvalue()).decode("utf-8") # Process the second image response = requests.get(url2) img2 = Image.open(BytesIO(response.content)).convert("RGB") rectangled_img2 = fill_rectangle_cropper(img2, "left_right") output2 = BytesIO() rectangled_img2.save(output2, format="JPEG") encoded_img2 = base64.b64encode(output2.getvalue()).decode("utf-8") return f""" Part of Idoia's Developer Portfolio - Innovating the Web

Rectangle Image Demo

Image will be rectangled with color filler where applicable.

Result 1:

Result 2:

Back

Image credit Adobe Stock User Umami Lab and Shutterstock User PhoArt101.
""" # Application Page @app.get("/application", response_class=HTMLResponse) def application_page(): return """ Part of Idoia's Developer Portfolio - Innovating the Web

Rectangle Image Application

Upload a JPG image to rectangle and fill with color filler. Suitable for youtube shorts, instagram reels and TikTok.







Back
Image credit Adobe Stock User Umami Lab and Shutterstock User PhoArt101.
""" @app.post("/upload/") async def upload_file(file: UploadFile = File(...), padding_type: str = Form(...)): try: # Await file upload contents = await file.read() img = Image.open(BytesIO(contents)).convert("RGB") # Apply padding based on user's choice rectangled_img = fill_rectangle_cropper(img,padding_type) # Save the rectangle image (original size) output = BytesIO() rectangled_img.save(output, format="JPEG") output.seek(0) # Encode the full-size image for download full_size_encoded_img = base64.b64encode(output.getvalue()).decode("utf-8") # Resize the image for display (512px by 512px) display_img = rectangled_img.copy() desired_width = 512 aspect_ratio = display_img.height / display_img.width desired_height = int(desired_width * aspect_ratio) display_img.thumbnail((desired_width, desired_height)) display_output = BytesIO() display_img.save(display_output, format="JPEG") display_output.seek(0) # Encode the resized display image display_encoded_img = base64.b64encode(display_output.getvalue()).decode("utf-8") # Return the HTML response return HTMLResponse( content=f""" Part of Idoia's Developer Portfolio - Innovating the Web

Image successfully rectangled!

Download Full-Size Image

Buy Me A Coffee
But what would really help me is a PRO subscription to Google Colab, Kaggle or Hugging Face. Many thanks.

Back

Image credit Adobe Stock User Umami Lab and Shutterstock User PhoArt101.
Buy Me A Coffee
But what would really help me is a PRO subscription to Google Colab, Kaggle or Hugging Face. Many thanks.
""", media_type="text/html" ) except Exception as e: return HTMLResponse(content=f"

An error occurred: {e}

", media_type="text/html") if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("PORT", 7860)))