File size: 6,220 Bytes
a966aaa
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
from PIL import Image, ImageDraw, ImageFont
import textwrap
import io

def create_quote_card(text, card_type="joke", title="Memory Forever"):
    """

    Generate a beautiful quote card image.

    

    Args:

        text (str): The quote/joke/memory text to display

        card_type (str): Type of card - "joke", "memory", or "motivation"

        title (str): Optional title text

    

    Returns:

        BytesIO: Image buffer that can be downloaded

    """
    # Card dimensions
    width, height = 1080, 1080
    
    # Create image
    img = Image.new('RGB', (width, height), color='white')
    draw = ImageDraw.Draw(img)
    
    # Define color schemes for different card types
    gradients = {
        'joke': {
            'top': (255, 75, 75),      # Red/Pink
            'bottom': (255, 120, 150),
            'accent': (255, 255, 255),
            'text': (255, 255, 255),
            'icon': '🎭'
        },
        'memory': {
            'top': (255, 215, 100),     # Yellow/Gold
            'bottom': (255, 180, 120),
            'accent': (139, 69, 19),
            'text': (80, 50, 20),
            'icon': 'πŸ’›'
        },
        'motivation': {
            'top': (100, 220, 150),     # Green
            'bottom': (80, 200, 180),
            'accent': (255, 255, 255),
            'text': (255, 255, 255),
            'icon': '✨'
        }
    }
    
    colors = gradients.get(card_type, gradients['joke'])
    
    # Draw gradient background
    for y in range(height):
        r = int(colors['top'][0] + (colors['bottom'][0] - colors['top'][0]) * y / height)
        g = int(colors['top'][1] + (colors['bottom'][1] - colors['top'][1]) * y / height)
        b = int(colors['top'][2] + (colors['bottom'][2] - colors['top'][2]) * y / height)
        draw.rectangle([(0, y), (width, y + 1)], fill=(r, g, b))
    
    # Add decorative elements
    add_decorative_elements(draw, width, height, colors['accent'], card_type)
    
    # Load fonts (fallback to default if custom not available)
    try:
        title_font = ImageFont.truetype("arial.ttf", 60)
        text_font = ImageFont.truetype("arial.ttf", 45)
        footer_font = ImageFont.truetype("arial.ttf", 35)
        icon_font = ImageFont.truetype("seguiemj.ttf", 80)  # For emoji
    except:
        # Fallback to default font
        title_font = ImageFont.load_default()
        text_font = ImageFont.load_default()
        footer_font = ImageFont.load_default()
        icon_font = ImageFont.load_default()
    
    # Draw icon at top
    icon = colors['icon']
    icon_bbox = draw.textbbox((0, 0), icon, font=icon_font)
    icon_width = icon_bbox[2] - icon_bbox[0]
    draw.text(((width - icon_width) // 2, 100), icon, font=icon_font, fill=colors['text'])
    
    # Draw title
    title_bbox = draw.textbbox((0, 0), title, font=title_font)
    title_width = title_bbox[2] - title_bbox[0]
    draw.text(((width - title_width) // 2, 220), title, font=title_font, fill=colors['text'])
    
    # Draw quote text with wrapping
    margin = 100
    max_width = width - (margin * 2)
    
    # Wrap text
    wrapped_text = wrap_text(text, text_font, max_width, draw)
    
    # Calculate text block height
    line_height = 60
    text_block_height = len(wrapped_text) * line_height
    
    # Start position for text (centered vertically)
    y_text = (height - text_block_height) // 2 + 50
    
    # Draw each line
    for line in wrapped_text:
        line_bbox = draw.textbbox((0, 0), line, font=text_font)
        line_width = line_bbox[2] - line_bbox[0]
        x = (width - line_width) // 2
        draw.text((x, y_text), line, font=text_font, fill=colors['text'])
        y_text += line_height
    
    # Draw footer
    footer_text = "Made with πŸ’– by Aman"
    footer_bbox = draw.textbbox((0, 0), footer_text, font=footer_font)
    footer_width = footer_bbox[2] - footer_bbox[0]
    draw.text(((width - footer_width) // 2, height - 120), footer_text, font=footer_font, fill=colors['text'])
    
    # Save to buffer
    buffer = io.BytesIO()
    img.save(buffer, format='PNG')
    buffer.seek(0)
    
    return buffer


def wrap_text(text, font, max_width, draw):
    """Wrap text to fit within max_width."""
    words = text.split()
    lines = []
    current_line = []
    
    for word in words:
        test_line = ' '.join(current_line + [word])
        bbox = draw.textbbox((0, 0), test_line, font=font)
        text_width = bbox[2] - bbox[0]
        
        if text_width <= max_width:
            current_line.append(word)
        else:
            if current_line:
                lines.append(' '.join(current_line))
                current_line = [word]
            else:
                # Word is too long, force it
                lines.append(word)
    
    if current_line:
        lines.append(' '.join(current_line))
    
    return lines


def add_decorative_elements(draw, width, height, color, card_type):
    """Add decorative elements to the card."""
    # Add subtle corner decorations
    corner_size = 100
    
    # Top left corner
    draw.arc([20, 20, corner_size, corner_size], start=180, end=270, fill=color, width=3)
    
    # Top right corner
    draw.arc([width - corner_size, 20, width - 20, corner_size], start=270, end=360, fill=color, width=3)
    
    # Bottom left corner
    draw.arc([20, height - corner_size, corner_size, height - 20], start=90, end=180, fill=color, width=3)
    
    # Bottom right corner
    draw.arc([width - corner_size, height - corner_size, width - 20, height - 20], start=0, end=90, fill=color, width=3)
    
    # Add small hearts or stars based on card type
    if card_type == 'memory':
        # Add small heart shapes
        for i in range(3):
            x = 80 + (i * 300)
            y = height - 200
            draw.ellipse([x, y, x + 20, y + 20], fill=color)
    elif card_type == 'motivation':
        # Add star-like dots
        for i in range(4):
            x = 100 + (i * 250)
            y = 320
            draw.ellipse([x, y, x + 15, y + 15], fill=color)