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,170 +197,80 @@ def generate_default_profile(
if square: if square:
desired_card_size = (450, 450) desired_card_size = (450, 450)
else: else:
# Slightly increase height to accommodate larger fonts
desired_card_size = (1050, 320) desired_card_size = (1050, 320)
# Define profile picture size and positions # Define profile picture size and positions
pfp_size = (270, 270) # Slightly smaller profile picture pfp_size = (270, 270)
pfp_x = 55 pfp_x = 15 # Slight padding from left
pfp_y = (desired_card_size[1] - pfp_size[1]) // 2 pfp_y = (desired_card_size[1] - pfp_size[1]) // 2
circle_x = pfp_x circle_x = pfp_x
circle_y = pfp_y circle_y = pfp_y
# Define the stats area to cover entire image # Create the dark background layer that covers everything
stats_area = ( dark_bg = Image.new("RGBA", desired_card_size, (0, 0, 0, 0))
0, # x1 - Start from very left edge dark_bg_draw = ImageDraw.Draw(dark_bg)
0, # y1 - Start from very top dark_bg_draw.rectangle((0, 0, desired_card_size[0], desired_card_size[1]), fill=(0, 0, 0, 180))
desired_card_size[0], # x2 - End at right edge
desired_card_size[1] # y2 - End at bottom
)
# Create the stats layer with glass effect # Create the stats layer
stats_layer = Image.new("RGBA", desired_card_size, (0, 0, 0, 0)) 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)
# Draw stats with improved styling
draw = ImageDraw.Draw(stats_layer) draw = ImageDraw.Draw(stats_layer)
# Add level text with enhanced modern styling # Stats positioning
level_text = f"LEVEL {level}" stats_x = pfp_x + pfp_size[0] + 30 # Start stats after profile picture
if prestige > 0: stats_y = 40 # Top padding
level_text = f"P{prestige}{level_text}"
# Use larger font for level display # Draw stats with consistent spacing
level_font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), 64) # Increased size title_font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), 32)
level_y = stats_area[1] + 20 value_font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), 32)
# Add subtle text shadow for depth # Balance and Rank stats
shadow_offset = 2 balance_y = stats_y
level_x = stats_area[0] + 30 # Move level text to left side 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))
# Draw level text with improved shadow rank_y = balance_y + 50
draw.text( draw.text((stats_x + 400, rank_y), "RANK:", font=title_font, fill=(200, 200, 200))
(level_x + shadow_offset, level_y + shadow_offset), draw.text((stats_x + 550, rank_y), f"#{humanize_number(position)}", font=value_font, fill=stat_color or (255, 255, 255))
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 # XP Text
title_font_size = 26 # Slightly smaller for better hierarchy xp_y = rank_y + 50
value_font_size = 30 # Kept larger for emphasis xp_text = f"XP: {humanize_number(current_xp)} / {humanize_number(next_xp)}"
title_font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), title_font_size) draw.text((stats_x + 400, xp_y), xp_text, font=value_font, fill=(255, 255, 255))
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 # Progress bar
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 = (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 = max(0, min(1, progress)) # Ensure progress is between 0 and 1
# Progress bar fill with gradient effect 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: if progress > 0:
progress_width = int(bar_width * progress) progress_width = int(bar_width * progress)
draw.rounded_rectangle( draw.rectangle((bar_x, bar_y, bar_x + progress_width, bar_y + bar_height), fill=level_bar_color or user_color)
(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 # Progress percentage
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_text = f"{int(progress * 100)}%"
percent_font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), 20) percent_font = ImageFont.truetype(str(font_path or imgtools.DEFAULT_FONT), 24)
percent_w = draw.textlength(percent_text, font=percent_font) percent_w = draw.textlength(percent_text, font=percent_font)
percent_x = bar_x + progress_width - percent_w - 10 percent_x = bar_x + 10 # Left align percentage
percent_y = bar_y + 2 percent_y = bar_y + (bar_height - 24) // 2 # Center in bar
# Draw percentage with improved shadow # Draw percentage
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((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}"
draw.text((15, 15), level_text, font=level_font, fill=user_color or (255, 255, 255))
# Composite the layers # Composite the layers
if not render_gif or (not pfp_animated and not bg_animated): if not render_gif or (not pfp_animated and not bg_animated):
if card.mode != "RGBA": if card.mode != "RGBA":
@ -371,32 +281,17 @@ def generate_default_profile(
# Fit the background to the desired size # Fit the background to the desired size
card = imgtools.fit_aspect_ratio(card, desired_card_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 # Create circular profile picture
pfp = pfp.resize(pfp_size, Image.Resampling.LANCZOS) pfp = pfp.resize(pfp_size, Image.Resampling.LANCZOS)
pfp = imgtools.make_profile_circle(pfp) pfp = imgtools.make_profile_circle(pfp)
# Position profile picture on the left # Create final image
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
final_image = Image.new("RGBA", desired_card_size, (0, 0, 0, 0)) final_image = Image.new("RGBA", desired_card_size, (0, 0, 0, 0))
# Add blur effect if enabled # Layer order: card -> dark background -> stats -> profile picture
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
final_image.paste(card, (0, 0), card) 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) final_image.paste(pfp, (pfp_x, pfp_y), pfp)
if debug: if debug: