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
Some checks are pending
Run pre-commit / Run pre-commit (push) Waiting to run
This commit is contained in:
parent
b3cf61b4ec
commit
bf4fbe7248
1 changed files with 64 additions and 169 deletions
|
@ -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:
|
||||
|
|
Loading…
Add table
Reference in a new issue