Betzpp / app.py
Reaperxxxx's picture
Update app.py
3de671d verified
raw
history blame
4.29 kB
import os
import uuid
import requests
from flask import Flask, request, send_file
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO
app = Flask(__name__)
# Ensure temp directory exists
TEMP_DIR = "temp"
os.makedirs(TEMP_DIR, exist_ok=True)
def load_font(font_path, size):
"""Load a font or fallback to default Arial."""
try:
return ImageFont.truetype(font_path, size)
except IOError:
return ImageFont.truetype("arial.ttf", size)
@app.route('/api')
def generate_profile():
# Get query parameters
name = request.args.get('name', 'Unknown')
rank = request.args.get('rank', 'Unranked')
balance = request.args.get('balance', '0')
next_rank = request.args.get('next_rank', 'Unknown')
pfp_url = request.args.get('pfp', None)
# Load background image
try:
bg = Image.open("bg.png").convert("RGBA") # Ensure transparency support
except IOError:
return "Error: Background image 'bg.png' not found.", 500
draw = ImageDraw.Draw(bg)
W, H = bg.size # Get background dimensions
# Load fonts
font_large = load_font("font.ttf", 45) # Name
font_medium = load_font("font.ttf", 35) # Rank, Balance
font_small = load_font("font.ttf", 30) # Next Rank
# Profile picture settings
pfp_size = 170
pfp_x = 50 # Align profile picture to the left
pfp_y = 50
pfp_path = os.path.join(TEMP_DIR, f"pfp_{uuid.uuid4().hex}.png")
# Load profile picture
try:
if pfp_url:
response = requests.get(pfp_url, timeout=5)
if response.status_code == 200:
pfp = Image.open(BytesIO(response.content)).convert("RGBA")
else:
raise ValueError("Invalid profile picture URL")
else:
pfp = Image.open("fallback.png").convert("RGBA")
# Resize profile picture
pfp = pfp.resize((pfp_size, pfp_size), Image.LANCZOS)
# Create circular mask
mask = Image.new("L", (pfp_size, pfp_size), 0)
draw_mask = ImageDraw.Draw(mask)
draw_mask.ellipse((0, 0, pfp_size, pfp_size), fill=255)
# Create a white border
border_size = 8
border = Image.new("RGBA", (pfp_size + border_size, pfp_size + border_size), (255, 255, 255, 255))
border_mask = Image.new("L", (pfp_size + border_size, pfp_size + border_size), 0)
border_draw = ImageDraw.Draw(border_mask)
border_draw.ellipse((0, 0, pfp_size + border_size, pfp_size + border_size), fill=255)
border.paste(pfp, (border_size // 2, border_size // 2), mask)
# Paste profile picture with border
bg.paste(border, (pfp_x - border_size // 2, pfp_y - border_size // 2), border_mask)
except Exception as e:
print(f"Error loading profile picture: {e}")
# Define text positions
text_x = pfp_x + pfp_size + 30 # Start text next to profile picture
text_y_start = pfp_y + 30
text_spacing = 60
text_color = (255, 255, 255)
# Function to handle text resizing for long names
def fit_text(text, max_width, base_font):
font = base_font
while draw.textlength(text, font=font) > max_width and font.size > 20:
font = load_font("font.ttf", font.size - 2)
return font
# Adjust name font size dynamically
name_font = fit_text(name, W - text_x - 50, font_large)
# Draw aligned text
draw.text((text_x, text_y_start), name, font=name_font, fill=text_color)
draw.text((text_x, text_y_start + text_spacing), f"Rank: {rank}", font=font_medium, fill=text_color)
draw.text((text_x, text_y_start + 2 * text_spacing), f"Balance: {balance}", font=font_medium, fill=text_color)
draw.text((text_x, text_y_start + 3 * text_spacing), f"Next Rank: {next_rank}", font=font_small, fill=text_color)
# Save final image
output_path = os.path.join(TEMP_DIR, f"profile_{uuid.uuid4().hex}.png")
bg.save(output_path)
# Send and delete image
response = send_file(output_path, mimetype='image/png')
# Cleanup saved files
if os.path.exists(output_path):
os.remove(output_path)
if os.path.exists(pfp_path):
os.remove(pfp_path)
return response
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7860, debug=True)