Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -11,15 +11,16 @@ app = Flask(__name__)
|
|
11 |
TEMP_DIR = "temp"
|
12 |
os.makedirs(TEMP_DIR, exist_ok=True)
|
13 |
|
|
|
14 |
def load_font(font_path, size):
|
15 |
-
"""Load a font or fallback to default Arial."""
|
16 |
try:
|
17 |
return ImageFont.truetype(font_path, size)
|
18 |
except IOError:
|
19 |
-
return ImageFont.
|
20 |
|
21 |
@app.route('/api')
|
22 |
def generate_profile():
|
|
|
23 |
# Get query parameters
|
24 |
name = request.args.get('name', 'Unknown')
|
25 |
rank = request.args.get('rank', 'Unranked')
|
@@ -38,16 +39,16 @@ def generate_profile():
|
|
38 |
|
39 |
# Load fonts
|
40 |
font_large = load_font("font.ttf", 45) # Name
|
41 |
-
font_medium = load_font("font.ttf", 35) # Rank
|
42 |
font_small = load_font("font.ttf", 30) # Next Rank
|
43 |
|
44 |
# Profile picture settings
|
45 |
pfp_size = 170
|
46 |
-
pfp_x = 50
|
47 |
-
pfp_y =
|
48 |
pfp_path = os.path.join(TEMP_DIR, f"pfp_{uuid.uuid4().hex}.png")
|
49 |
|
50 |
-
# Load profile picture
|
51 |
try:
|
52 |
if pfp_url:
|
53 |
response = requests.get(pfp_url, timeout=5)
|
@@ -58,34 +59,32 @@ def generate_profile():
|
|
58 |
else:
|
59 |
pfp = Image.open("fallback.png").convert("RGBA")
|
60 |
|
61 |
-
# Resize profile picture
|
62 |
pfp = pfp.resize((pfp_size, pfp_size), Image.LANCZOS)
|
63 |
-
|
64 |
-
# Create circular mask
|
65 |
mask = Image.new("L", (pfp_size, pfp_size), 0)
|
66 |
-
|
67 |
-
|
68 |
|
69 |
-
# Create a
|
70 |
-
border_size =
|
71 |
border = Image.new("RGBA", (pfp_size + border_size, pfp_size + border_size), (255, 255, 255, 255))
|
72 |
border_mask = Image.new("L", (pfp_size + border_size, pfp_size + border_size), 0)
|
73 |
border_draw = ImageDraw.Draw(border_mask)
|
74 |
border_draw.ellipse((0, 0, pfp_size + border_size, pfp_size + border_size), fill=255)
|
75 |
border.paste(pfp, (border_size // 2, border_size // 2), mask)
|
76 |
|
77 |
-
# Paste profile picture
|
78 |
bg.paste(border, (pfp_x - border_size // 2, pfp_y - border_size // 2), border_mask)
|
79 |
except Exception as e:
|
80 |
print(f"Error loading profile picture: {e}")
|
81 |
|
82 |
-
#
|
83 |
-
text_x = pfp_x + pfp_size +
|
84 |
-
|
85 |
-
text_spacing =
|
86 |
text_color = (255, 255, 255)
|
87 |
|
88 |
-
# Function to
|
89 |
def fit_text(text, max_width, base_font):
|
90 |
font = base_font
|
91 |
while draw.textlength(text, font=font) > max_width and font.size > 20:
|
@@ -95,11 +94,11 @@ def generate_profile():
|
|
95 |
# Adjust name font size dynamically
|
96 |
name_font = fit_text(name, W - text_x - 50, font_large)
|
97 |
|
98 |
-
# Draw aligned
|
99 |
-
draw.text((text_x,
|
100 |
-
draw.text((text_x,
|
101 |
-
draw.text((text_x,
|
102 |
-
draw.text((text_x,
|
103 |
|
104 |
# Save final image
|
105 |
output_path = os.path.join(TEMP_DIR, f"profile_{uuid.uuid4().hex}.png")
|
|
|
11 |
TEMP_DIR = "temp"
|
12 |
os.makedirs(TEMP_DIR, exist_ok=True)
|
13 |
|
14 |
+
# Load fonts safely
|
15 |
def load_font(font_path, size):
|
|
|
16 |
try:
|
17 |
return ImageFont.truetype(font_path, size)
|
18 |
except IOError:
|
19 |
+
return ImageFont.load_default()
|
20 |
|
21 |
@app.route('/api')
|
22 |
def generate_profile():
|
23 |
+
""" Generate a profile card with user details and a profile picture. """
|
24 |
# Get query parameters
|
25 |
name = request.args.get('name', 'Unknown')
|
26 |
rank = request.args.get('rank', 'Unranked')
|
|
|
39 |
|
40 |
# Load fonts
|
41 |
font_large = load_font("font.ttf", 45) # Name
|
42 |
+
font_medium = load_font("font.ttf", 35) # Rank & Balance
|
43 |
font_small = load_font("font.ttf", 30) # Next Rank
|
44 |
|
45 |
# Profile picture settings
|
46 |
pfp_size = 170
|
47 |
+
pfp_x = 50
|
48 |
+
pfp_y = H // 2 - pfp_size // 2 # Center vertically
|
49 |
pfp_path = os.path.join(TEMP_DIR, f"pfp_{uuid.uuid4().hex}.png")
|
50 |
|
51 |
+
# Load profile picture or fallback
|
52 |
try:
|
53 |
if pfp_url:
|
54 |
response = requests.get(pfp_url, timeout=5)
|
|
|
59 |
else:
|
60 |
pfp = Image.open("fallback.png").convert("RGBA")
|
61 |
|
62 |
+
# Resize and mask the profile picture (circular crop)
|
63 |
pfp = pfp.resize((pfp_size, pfp_size), Image.LANCZOS)
|
|
|
|
|
64 |
mask = Image.new("L", (pfp_size, pfp_size), 0)
|
65 |
+
mask_draw = ImageDraw.Draw(mask)
|
66 |
+
mask_draw.ellipse((0, 0, pfp_size, pfp_size), fill=255)
|
67 |
|
68 |
+
# Create a border
|
69 |
+
border_size = 10
|
70 |
border = Image.new("RGBA", (pfp_size + border_size, pfp_size + border_size), (255, 255, 255, 255))
|
71 |
border_mask = Image.new("L", (pfp_size + border_size, pfp_size + border_size), 0)
|
72 |
border_draw = ImageDraw.Draw(border_mask)
|
73 |
border_draw.ellipse((0, 0, pfp_size + border_size, pfp_size + border_size), fill=255)
|
74 |
border.paste(pfp, (border_size // 2, border_size // 2), mask)
|
75 |
|
76 |
+
# Paste profile picture onto background
|
77 |
bg.paste(border, (pfp_x - border_size // 2, pfp_y - border_size // 2), border_mask)
|
78 |
except Exception as e:
|
79 |
print(f"Error loading profile picture: {e}")
|
80 |
|
81 |
+
# **TEXT POSITIONING (Fix for scattered text)**
|
82 |
+
text_x = pfp_x + pfp_size + 40 # Place text beside the profile picture
|
83 |
+
text_y = pfp_y # Align with profile picture
|
84 |
+
text_spacing = 55 # Space between text lines
|
85 |
text_color = (255, 255, 255)
|
86 |
|
87 |
+
# Function to resize text dynamically
|
88 |
def fit_text(text, max_width, base_font):
|
89 |
font = base_font
|
90 |
while draw.textlength(text, font=font) > max_width and font.size > 20:
|
|
|
94 |
# Adjust name font size dynamically
|
95 |
name_font = fit_text(name, W - text_x - 50, font_large)
|
96 |
|
97 |
+
# **Draw text (All properly aligned)**
|
98 |
+
draw.text((text_x, text_y), name, font=name_font, fill=text_color)
|
99 |
+
draw.text((text_x, text_y + text_spacing), f"Rank: {rank}", font=font_medium, fill=text_color)
|
100 |
+
draw.text((text_x, text_y + 2 * text_spacing), f"Balance: {balance}", font=font_medium, fill=text_color)
|
101 |
+
draw.text((text_x, text_y + 3 * text_spacing), f"Next Rank: {next_rank}", font=font_small, fill=text_color)
|
102 |
|
103 |
# Save final image
|
104 |
output_path = os.path.join(TEMP_DIR, f"profile_{uuid.uuid4().hex}.png")
|