Refactor default.py to streamline profile card rendering, including adjustments to background layers, improved stats layout, and enhanced visibility of XP and progress percentage. Simplify the design by removing unnecessary elements and optimizing positioning for a cleaner aesthetic.
Some checks are pending
Run pre-commit / Run pre-commit (push) Waiting to run

This commit is contained in:
Valerie 2025-05-26 21:59:41 -04:00
parent b3cf61b4ec
commit bf4fbe7248

View file

@ -197,169 +197,79 @@ def generate_default_profile(
if square:
desired_card_size = (450, 450)
else:
# Slightly increase height to accommodate larger fonts
desired_card_size = (1050, 320)
# Define profile picture size and positions
pfp_size = (270, 270) # Slightly smaller profile picture
pfp_x = 55
pfp_size = (270, 270)
pfp_x = 15 # Slight padding from left
pfp_y = (desired_card_size[1] - pfp_size[1]) // 2
circle_x = pfp_x
circle_y = pfp_y
# Define the stats area to cover entire image
stats_area = (
0, # x1 - Start from very left edge
0, # y1 - Start from very top
desired_card_size[0], # x2 - End at right edge
desired_card_size[1] # y2 - End at bottom
)
# Create the stats layer with glass effect
stats_layer = Image.new("RGBA", desired_card_size, (0, 0, 0, 0))
# Create a darker glass morphism effect for entire background
glass = Image.new("RGBA", desired_card_size, (0, 0, 0, 0))
glass_draw = ImageDraw.Draw(glass)
glass_draw.rounded_rectangle(stats_area, radius=15, fill=(0, 0, 0, 160)) # Darker background for better readability
# Add a subtle gradient overlay for depth
gradient = Image.new("RGBA", desired_card_size, (0, 0, 0, 0))
gradient_draw = ImageDraw.Draw(gradient)
for i in range(40):
opacity = int(35 * (1 - i/40)) # Reduced opacity for subtler effect
gradient_draw.rounded_rectangle(
(stats_area[0], stats_area[1]+i, stats_area[2], stats_area[3]),
radius=15,
fill=(255, 255, 255, opacity)
)
# Composite the glass effect
stats_layer = Image.alpha_composite(stats_layer, glass)
stats_layer = Image.alpha_composite(stats_layer, gradient)
# Create the dark background layer that covers everything
dark_bg = Image.new("RGBA", desired_card_size, (0, 0, 0, 0))
dark_bg_draw = ImageDraw.Draw(dark_bg)
dark_bg_draw.rectangle((0, 0, desired_card_size[0], desired_card_size[1]), fill=(0, 0, 0, 180))
# Draw stats with improved styling
# Create the stats layer
stats_layer = Image.new("RGBA", desired_card_size, (0, 0, 0, 0))
draw = ImageDraw.Draw(stats_layer)
# Stats positioning
stats_x = pfp_x + pfp_size[0] + 30 # Start stats after profile picture
stats_y = 40 # Top padding
# Add level text with enhanced modern styling
# Draw stats with consistent spacing
title_font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), 32)
value_font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), 32)
# Balance and Rank stats
balance_y = stats_y
draw.text((stats_x + 400, balance_y), "BALANCE:", font=title_font, fill=(200, 200, 200))
draw.text((stats_x + 550, balance_y), f"{humanize_number(balance)} CREDITS", font=value_font, fill=stat_color or (255, 255, 255))
rank_y = balance_y + 50
draw.text((stats_x + 400, rank_y), "RANK:", font=title_font, fill=(200, 200, 200))
draw.text((stats_x + 550, rank_y), f"#{humanize_number(position)}", font=value_font, fill=stat_color or (255, 255, 255))
# XP Text
xp_y = rank_y + 50
xp_text = f"XP: {humanize_number(current_xp)} / {humanize_number(next_xp)}"
draw.text((stats_x + 400, xp_y), xp_text, font=value_font, fill=(255, 255, 255))
# Progress bar
progress = (current_xp - previous_xp) / (next_xp - previous_xp) if next_xp > previous_xp else 0
progress = max(0, min(1, progress)) # Ensure progress is between 0 and 1
bar_width = desired_card_size[0] - 30 # Full width with padding
bar_height = 40
bar_x = 15
bar_y = desired_card_size[1] - bar_height - 15 # Bottom padding
# Progress bar background
draw.rectangle((bar_x, bar_y, bar_x + bar_width, bar_y + bar_height), fill=(50, 50, 50))
# Progress bar fill
if progress > 0:
progress_width = int(bar_width * progress)
draw.rectangle((bar_x, bar_y, bar_x + progress_width, bar_y + bar_height), fill=level_bar_color or user_color)
# Progress percentage
percent_text = f"{int(progress * 100)}%"
percent_font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), 24)
percent_w = draw.textlength(percent_text, font=percent_font)
percent_x = bar_x + 10 # Left align percentage
percent_y = bar_y + (bar_height - 24) // 2 # Center in bar
# Draw percentage
draw.text((percent_x, percent_y), percent_text, font=percent_font, fill=(255, 255, 255))
# Level text
level_font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), 48)
level_text = f"LEVEL {level}"
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), 64) # Increased size
level_y = stats_area[1] + 20
# Add subtle text shadow for depth
shadow_offset = 2
level_x = stats_area[0] + 30 # Move level text to left side
# Draw level text with improved shadow
draw.text(
(level_x + shadow_offset, level_y + shadow_offset),
level_text,
font=level_font,
fill=(0, 0, 0, 60) # More subtle shadow
)
draw.text(
(level_x, level_y),
level_text,
font=level_font,
fill=user_color
)
# Stats section with improved layout
title_font_size = 26 # Slightly smaller for better hierarchy
value_font_size = 30 # Kept larger for emphasis
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 = 50 # Increased spacing between stats
# Starting positions - moved down and left
start_x = stats_area[0] + 40
start_y = level_y + 100 # More space after level text
# Helper function for stat rendering with improved spacing
def draw_stat(x_pos, y_pos, icon, title, value, color=stat_color):
# Draw icon with subtle glow
draw.text((x_pos, y_pos), icon, font=value_font, fill=color)
# Draw title with modern styling
title_x = x_pos + 40
draw.text((title_x, y_pos), f"{title}:", font=title_font, fill=(200, 200, 200)) # Slightly dimmer
# Calculate value position
title_width = draw.textlength(f"{title}:", font=title_font)
value_x = title_x + title_width + 15
# Draw value with subtle shadow
draw.text((value_x + 1, y_pos + 1), value, font=value_font, fill=(0, 0, 0, 40))
draw.text((value_x, y_pos), value, font=value_font, fill=color)
return spacing
# Draw stats in two columns with better spacing
left_column_x = start_x
right_column_x = start_x + 380 # Increased column separation
current_y = start_y
# 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
current_y = start_y
if balance is not None:
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 - moved to bottom
bar_width = stats_area[2] - stats_area[0] - 60 # Full width progress bar
bar_height = 25 # Slightly thinner
bar_x = stats_area[0] + 30
bar_y = stats_area[3] - 60 # Move up from bottom
# Progress bar background with modern blur effect
draw.rounded_rectangle(
(bar_x, bar_y, bar_x + bar_width, bar_y + bar_height),
radius=bar_height//2,
fill=(0, 0, 0, 40) # Very subtle background
)
# Calculate progress
progress = (current_xp - previous_xp) / (next_xp - previous_xp) if next_xp > previous_xp else 0
progress = max(0, min(1, progress)) # Ensure progress is between 0 and 1
# Progress bar fill with gradient effect
if progress > 0:
progress_width = int(bar_width * progress)
draw.rounded_rectangle(
(bar_x, bar_y, bar_x + progress_width, bar_y + bar_height),
radius=bar_height//2,
fill=level_bar_color or user_color
)
# XP Text with improved visibility
xp_font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), 22)
xp_text = f"XP: {humanize_number(current_xp)} / {humanize_number(next_xp)}"
xp_w = draw.textlength(xp_text, font=xp_font)
xp_x = bar_x + (bar_width - xp_w) / 2
xp_y = bar_y - 30
# Draw XP text with improved shadow
draw.text((xp_x + 1, xp_y + 1), xp_text, font=xp_font, fill=(0, 0, 0, 80))
draw.text((xp_x, xp_y), xp_text, font=xp_font, fill=(255, 255, 255))
# Progress percentage with improved visibility
percent_text = f"{int(progress * 100)}%"
percent_font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), 20)
percent_w = draw.textlength(percent_text, font=percent_font)
percent_x = bar_x + progress_width - percent_w - 10
percent_y = bar_y + 2
# Draw percentage with improved shadow
draw.text((percent_x + 1, percent_y + 1), percent_text, font=percent_font, fill=(0, 0, 0, 80))
draw.text((percent_x, percent_y), percent_text, font=percent_font, fill=(255, 255, 255))
draw.text((15, 15), level_text, font=level_font, fill=user_color or (255, 255, 255))
# Composite the layers
if not render_gif or (not pfp_animated and not bg_animated):
@ -371,32 +281,17 @@ def generate_default_profile(
# Fit the background to the desired size
card = imgtools.fit_aspect_ratio(card, desired_card_size)
# Round the card corners
card = imgtools.round_image_corners(card, 20)
# Create circular profile picture
pfp = pfp.resize(pfp_size, Image.Resampling.LANCZOS)
pfp = imgtools.make_profile_circle(pfp)
# Position profile picture on the left
pfp_x = 55
pfp_y = (desired_card_size[1] - pfp_size[1]) // 2
# Define circle positions for animated profiles
circle_x = pfp_x
circle_y = pfp_y
# Create a new image for final composition
# Create final image
final_image = Image.new("RGBA", desired_card_size, (0, 0, 0, 0))
# Add blur effect if enabled
if blur:
blur_section = imgtools.blur_section(card, (stats_area[0], 0, card.width, card.height))
card.paste(blur_section, (stats_area[0], 0), blur_section)
# Paste layers in correct order
# Layer order: card -> dark background -> stats -> profile picture
final_image.paste(card, (0, 0), card)
final_image.paste(stats_layer, (0, 0), stats_layer)
final_image = Image.alpha_composite(final_image, dark_bg)
final_image = Image.alpha_composite(final_image, stats_layer)
final_image.paste(pfp, (pfp_x, pfp_y), pfp)
if debug: