用Python打造暖心生日惊喜:从绘图到自动发送的完整指南
生日贺卡早已不再是简单的纸质问候,在这个数字化时代,用代码亲手为朋友定制一张动态贺卡,或许是最特别的祝福方式。想象一下,当朋友在生日当天收到一封自动发送的邮件,打开附件发现是一张由你编写的程序生成的个性化贺卡,上面不仅有精美的蛋糕动画,还有专属的祝福语——这种惊喜感是普通礼物难以比拟的。
1. 环境准备与基础绘图
在开始我们的创意编程之旅前,需要确保开发环境就绪。推荐使用Python 3.6+版本,并安装必要的图形库:
pip install turtle pillowTurtle是Python内置的绘图模块,非常适合初学者创建2D图形。我们先从一个简单的蛋糕轮廓开始:
import turtle as t def setup_canvas(): t.bgcolor("#F5F5F5") # 浅灰色背景 t.setup(800, 600) # 设置画布大小 t.speed(10) # 中等绘制速度 def draw_plate(): t.penup() t.goto(-150, -100) t.pendown() t.color("#E0E0E0", "#FFFFFF") t.begin_fill() t.circle(150, 180) # 绘制半圆作为盘子 t.end_fill() setup_canvas() draw_plate() t.done()这段代码会创建一个简单的蛋糕底盘,运行后你将看到:
- 浅灰色背景的绘图窗口
- 底部有一个白色半圆形盘子
- 绘图完成后窗口保持打开状态
提示:在交互式环境中运行代码时,可能需要手动关闭图形窗口才能继续执行后续代码
2. 构建多层蛋糕结构
真实的生日蛋糕通常是多层的,我们可以用函数封装每层的绘制逻辑:
def cake_layer(x, y, width, height, color): t.penup() t.goto(x, y) t.pendown() t.color(color) t.begin_fill() for _ in range(2): # 绘制矩形 t.forward(width) t.left(90) t.forward(height) t.left(90) t.end_fill() # 顶部装饰线 t.penup() t.goto(x, y+height) t.pendown() t.pensize(3) t.forward(width) t.pensize(1)现在可以组合多个蛋糕层:
setup_canvas() draw_plate() # 底层蛋糕 cake_layer(-120, -80, 240, 60, "#FFD3B6") # 浅橙色 # 中层蛋糕 cake_layer(-90, -20, 180, 50, "#FFAAA5") # 粉红色 # 顶层蛋糕 cake_layer(-60, 30, 120, 40, "#A8E6CF") # 薄荷绿 t.done()各层参数对比:
| 层级 | 宽度 | 高度 | Y坐标 | 颜色代码 | 视觉效果 |
|---|---|---|---|---|---|
| 底层 | 240 | 60 | -80 | #FFD3B6 | 宽大稳固 |
| 中层 | 180 | 50 | -20 | #FFAAA5 | 过渡衔接 |
| 顶层 | 120 | 40 | 30 | #A8E6CF | 精致小巧 |
3. 添加动态元素与个性化文本
静态图像已经足够漂亮,但加入动态元素会让贺卡更加生动。我们可以添加闪烁的蜡烛火焰:
import random import time def flickering_flame(x, y): for _ in range(5): # 火焰闪烁效果 t.penup() t.goto(x, y) t.pendown() flame_color = random.choice(["#FFD700", "#FF6347", "#FFA500"]) t.color(flame_color) t.begin_fill() t.circle(10) # 火焰基础形状 t.end_fill() time.sleep(0.3) t.clear() # 清除当前火焰准备绘制下一个个性化文本添加也很关键,我们可以让用户输入祝福语:
def personalized_message(name): t.penup() t.goto(-200, 200) t.pendown() t.color("#8B00FF") message = f"Happy Birthday, {name}!" t.write(message, font=("Arial", 24, "bold"))组合所有元素:
def complete_card(name): setup_canvas() draw_plate() cake_layer(-120, -80, 240, 60, "#FFD3B6") cake_layer(-90, -20, 180, 50, "#FFAAA5") cake_layer(-60, 30, 120, 40, "#A8E6CF") # 添加蜡烛 for x_pos in [-80, -40, 0, 40, 80]: cake_layer(x_pos-5, 70, 10, 30, "#FFFFFF") # 白色蜡烛 flickering_flame(x_pos, 110) # 火焰效果 personalized_message(name) t.done()4. 自动化发送与高级功能
完成贺卡设计后,我们可以实现自动发送功能。首先需要将绘图保存为图片:
from PIL import ImageGrab import datetime def save_card(name): # 获取当前日期作为文件名 date_str = datetime.datetime.now().strftime("%Y%m%d") filename = f"birthday_card_{name}_{date_str}.png" # 截取Turtle绘图区域 img = ImageGrab.grab(bbox=(0, 0, 800, 600)) img.save(filename) return filename然后配置自动邮件发送:
import smtplib from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.image import MIMEImage def send_email(to_addr, name, card_path): # 配置邮件基本信息 msg = MIMEMultipart() msg["From"] = "your_email@example.com" msg["To"] = to_addr msg["Subject"] = f"Special Birthday Wish for {name}" # 添加文本内容 body = f""" <html> <body> <p>Dear {name},</p> <p>Wishing you a fantastic birthday!</p> <p>This card was generated just for you with Python code.</p> <img src="cid:image1" width="400"> </body> </html> """ msg.attach(MIMEText(body, "html")) # 添加图片附件 with open(card_path, "rb") as f: img = MIMEImage(f.read()) img.add_header("Content-ID", "<image1>") msg.attach(img) # 发送邮件 with smtplib.SMTP("smtp.example.com", 587) as server: server.starttls() server.login("your_email@example.com", "your_password") server.send_message(msg)完整流程整合:
def auto_birthday_wish(name, email): # 生成贺卡 complete_card(name) # 保存图片 card_file = save_card(name) # 发送邮件 send_email(email, name, card_file) print(f"Birthday card sent to {name} at {email}")注意:在实际使用前,需要配置真实的SMTP服务器信息和邮箱凭证
5. 创意扩展与个性化定制
基础功能实现后,我们可以考虑更多个性化选项:
- 主题颜色定制:允许用户选择蛋糕的主色调
- 动画效果增强:添加更多动态元素,如飘落的花瓣
- 音乐集成:在打开贺卡时播放生日歌
- 响应式设计:根据接收设备调整贺卡尺寸
颜色主题选择示例:
THEMES = { "classic": {"base": "#FFD3B6", "middle": "#FFAAA5", "top": "#A8E6CF"}, "chocolate": {"base": "#6B4423", "middle": "#8B4513", "top": "#A0522D"}, "berry": {"base": "#FFB6C1", "middle": "#FF69B4", "top": "#C71585"} } def apply_theme(theme_name): return THEMES.get(theme_name, THEMES["classic"])用户交互改进:
def get_user_input(): print("Create a Personalized Birthday Card") print("----------------------------------") name = input("Recipient's name: ") email = input("Recipient's email: ") theme = input("Theme (classic/chocolate/berry): ") message = input("Custom message (optional): ") return { "name": name, "email": email, "theme": theme, "message": message or None }最终的主程序逻辑:
def main(): user_input = get_user_input() colors = apply_theme(user_input["theme"]) # 使用用户选择的颜色重新定义蛋糕层 def custom_cake(): cake_layer(-120, -80, 240, 60, colors["base"]) cake_layer(-90, -20, 180, 50, colors["middle"]) cake_layer(-60, 30, 120, 40, colors["top"]) # 生成并发送贺卡 complete_card(user_input["name"]) card_file = save_card(user_input["name"]) send_email(user_input["email"], user_input["name"], card_file) if __name__ == "__main__": main()在实际项目中,我发现最让收件人惊喜的往往不是技术复杂度,而是那些精心设计的个性化细节。比如在蛋糕上添加收件人名字的首字母,或者根据他们的兴趣爱好添加相关元素(如足球、音乐符号等)。这些细节让贺卡从"好看的自动生成图片"变成了"专属于TA的特别礼物"。