Refine profile card generation in default.py by adjusting layout dimensions for improved spacing, reducing font sizes, and enhancing the stats area design. Update the progress bar and XP text positioning for better visual clarity and overall aesthetics.
Some checks are pending
Run pre-commit / Run pre-commit (push) Waiting to run

This commit is contained in:
Valerie 2025-05-25 22:05:36 -04:00
parent 4c99430d95
commit 694b91b69d

View file

@ -196,15 +196,15 @@ def generate_default_profile(
if square:
desired_card_size = (450, 450)
else:
# Reduce height for better proportions
desired_card_size = (1050, 350)
# Keep width but adjust height for better spacing
desired_card_size = (1050, 300)
# Define the stats area with a modern glass effect
stats_area = (
400, # x1 - Start after profile picture
20, # y1 - Start near top
1000 if not square else 430, # x2 - End near right edge
330 if not square else 430 # y2 - End near bottom
380, # x1 - Start after profile picture (moved left slightly)
15, # y1 - Start near top
1020, # x2 - End near right edge
285 # y2 - Reduced height
)
# Create the stats layer with glass effect
@ -213,7 +213,7 @@ def generate_default_profile(
# Create a semi-transparent background for stats with modern blur effect
glass = Image.new("RGBA", desired_card_size, (0, 0, 0, 0))
glass_draw = ImageDraw.Draw(glass)
glass_draw.rounded_rectangle(stats_area, radius=25, fill=(0, 0, 0, 95))
glass_draw.rounded_rectangle(stats_area, radius=20, fill=(0, 0, 0, 95))
# Add a subtle gradient overlay for depth
gradient = Image.new("RGBA", desired_card_size, (0, 0, 0, 0))
@ -222,7 +222,7 @@ def generate_default_profile(
opacity = int(60 * (1 - i/30))
gradient_draw.rounded_rectangle(
(stats_area[0], stats_area[1]+i, stats_area[2], stats_area[3]),
radius=25,
radius=20,
fill=(255, 255, 255, opacity)
)
@ -235,7 +235,7 @@ def generate_default_profile(
for i in range(3):
border_draw.rounded_rectangle(
(stats_area[0]-i, stats_area[1]-i, stats_area[2]+i, stats_area[3]+i),
radius=25,
radius=20,
outline=(155, 17, 30, 100-i*30),
width=1
)
@ -248,68 +248,92 @@ def generate_default_profile(
if prestige > 0:
level_text = f"P{prestige}{level_text}"
# Use larger font for level display
level_font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), 56)
level_y = stats_area[1] + 15
# Use smaller font for level display to prevent overlap
level_font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), 42)
level_y = stats_area[1] + 10
# Add subtle text shadow for depth
shadow_offset = 2
draw.text(
(stats_area[0] + 20 + shadow_offset, level_y + shadow_offset),
(stats_area[0] + 15 + shadow_offset, level_y + shadow_offset),
level_text,
font=level_font,
fill=(0, 0, 0, 100)
)
draw.text(
(stats_area[0] + 20, level_y),
(stats_area[0] + 15, level_y),
level_text,
font=level_font,
fill=user_color
)
# Stats section with improved layout
title_font_size = 24
value_font_size = 28
title_font_size = 20 # Reduced font size
value_font_size = 24 # Reduced font size
title_font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), title_font_size)
value_font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), value_font_size)
spacing = 45 # Vertical spacing between stats
spacing = 35 # Reduced spacing between stats
# Starting positions
start_x = stats_area[0] + 20
start_y = level_y + 80
start_x = stats_area[0] + 15
start_y = level_y + 60 # Reduced gap after level
# Helper function for stat rendering
def draw_stat(y_pos, icon, title, value, color=stat_color):
# Helper function for stat rendering with improved spacing
def draw_stat(x_pos, y_pos, icon, title, value, color=stat_color):
# Draw icon
draw.text((start_x, y_pos), icon, font=value_font, fill=color)
draw.text((x_pos, y_pos + 2), icon, font=value_font, fill=color)
# Draw title
draw.text((start_x + 40, y_pos), f"{title}:", font=title_font, fill=(200, 200, 200))
title_x = x_pos + 30
draw.text((title_x, y_pos), f"{title}:", font=title_font, fill=(200, 200, 200))
# Calculate value position
title_width = draw.textlength(f"{title}:", font=title_font)
# Draw value with shadow for depth
value_x = start_x + 40
value_y = y_pos + title_font_size + 2
draw.text((value_x + 1, value_y + 1), value, font=value_font, fill=(0, 0, 0, 100))
draw.text((value_x, value_y), value, font=value_font, fill=color)
return spacing + title_font_size + 5
value_x = title_x + title_width + 5
draw.text((value_x + 1, y_pos + 1), value, font=value_font, fill=(0, 0, 0, 100))
draw.text((value_x, y_pos), value, font=value_font, fill=color)
return spacing
# Draw each stat with title and value
# Draw stats in two columns with better spacing
left_column_x = start_x
right_column_x = stats_area[0] + 300
current_y = start_y
current_y += draw_stat(current_y, "💬", "Messages", f"{humanize_number(messages)} sent")
current_y += draw_stat(current_y, "🎤", "Voice Time", imgtools.abbreviate_time(voicetime))
current_y += draw_stat(current_y, "", "Stars", humanize_number(stars))
# Left column stats
current_y += draw_stat(left_column_x, current_y, "💬", "Messages", f"{humanize_number(messages)}")
current_y += draw_stat(left_column_x, current_y, "🎤", "Voice", imgtools.abbreviate_time(voicetime))
current_y += draw_stat(left_column_x, current_y, "", "Stars", humanize_number(stars))
# Right column stats
right_x = stats_area[0] + 300
current_y = start_y
if balance is not None:
current_y += draw_stat(current_y, "💰", "Balance", f"{humanize_number(balance)} {currency_name}")
current_y += draw_stat(current_y, "🏆", "Rank", f"#{humanize_number(position)}")
current_y += draw_stat(right_column_x, current_y, "💰", "Balance", f"{humanize_number(balance)} {currency_name}")
current_y += draw_stat(right_column_x, current_y, "🏆", "Rank", f"#{humanize_number(position)}")
# Progress bar with modern design
bar_width = stats_area[2] - stats_area[0] - 40
bar_height = 30
bar_y = stats_area[3] - 60
# Progress bar with modern design - moved down
bar_width = stats_area[2] - stats_area[0] - 30 # Slightly narrower
bar_height = 25 # Slightly shorter
bar_y = stats_area[3] - 45 # Move up from bottom
progress = (current_xp - previous_xp) / (next_xp - previous_xp)
# XP text above progress bar
xp_font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), 20) # Smaller font
xp_text = f"EXP: {humanize_number(current_xp)} / {humanize_number(next_xp)}"
xp_x = start_x + (bar_width - draw.textlength(xp_text, font=xp_font)) // 2
# Draw XP text with shadow
draw.text(
(xp_x + 1, bar_y - 25 + 1), # Moved closer to bar
xp_text,
font=xp_font,
fill=(0, 0, 0, 100)
)
draw.text(
(xp_x, bar_y - 25), # Moved closer to bar
xp_text,
font=xp_font,
fill=(255, 255, 255)
)
# Create progress bar background with gradient
bar_bg = Image.new("RGBA", (bar_width, bar_height), (0, 0, 0, 100))
progress_width = max(1, int(bar_width * progress))
@ -341,26 +365,7 @@ def generate_default_profile(
stats_layer.paste(bar_bg, (start_x, bar_y), bar_bg)
stats_layer.paste(bar_progress_masked, (start_x, bar_y), bar_progress_masked)
# XP text with improved styling
xp_font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), 24)
xp_text = f"EXP: {humanize_number(current_xp)} / {humanize_number(next_xp)}"
xp_x = start_x + (bar_width - draw.textlength(xp_text, font=xp_font)) // 2
# Draw XP text with shadow
draw.text(
(xp_x + 1, bar_y - 30 + 1),
xp_text,
font=xp_font,
fill=(0, 0, 0, 100)
)
draw.text(
(xp_x, bar_y - 30),
xp_text,
font=xp_font,
fill=(255, 255, 255)
)
# Progress percentage
# Progress percentage below bar
percent_text = f"{int(progress * 100)}%"
percent_x = start_x + (bar_width - draw.textlength(percent_text, font=xp_font)) // 2
draw.text(
@ -383,15 +388,15 @@ def generate_default_profile(
card = imgtools.fit_aspect_ratio(card, desired_card_size)
# Round the card corners
card = imgtools.round_image_corners(card, 25)
card = imgtools.round_image_corners(card, 20)
# Create circular profile picture
pfp_size = (300, 300) # Slightly smaller profile picture
pfp_size = (270, 270) # Slightly smaller profile picture
pfp = pfp.resize(pfp_size, Image.Resampling.LANCZOS)
pfp = imgtools.make_profile_circle(pfp)
# Position profile picture on the left
pfp_x = 50
pfp_x = 55
pfp_y = (desired_card_size[1] - pfp_size[1]) // 2
# Create a new image for final composition