news 2026/6/2 1:40:20

用Python给朋友一个惊喜:自动化生成个性化生日贺卡(附完整源码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
用Python给朋友一个惊喜:自动化生成个性化生日贺卡(附完整源码)

用Python打造暖心生日惊喜:从绘图到自动发送的完整指南

生日贺卡早已不再是简单的纸质问候,在这个数字化时代,用代码亲手为朋友定制一张动态贺卡,或许是最特别的祝福方式。想象一下,当朋友在生日当天收到一封自动发送的邮件,打开附件发现是一张由你编写的程序生成的个性化贺卡,上面不仅有精美的蛋糕动画,还有专属的祝福语——这种惊喜感是普通礼物难以比拟的。

1. 环境准备与基础绘图

在开始我们的创意编程之旅前,需要确保开发环境就绪。推荐使用Python 3.6+版本,并安装必要的图形库:

pip install turtle pillow

Turtle是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坐标颜色代码视觉效果
底层24060-80#FFD3B6宽大稳固
中层18050-20#FFAAA5过渡衔接
顶层1204030#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的特别礼物"。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/2 1:30:58

如何在STM32上实现Arduino开发:Keilduino框架深度解析

如何在STM32上实现Arduino开发&#xff1a;Keilduino框架深度解析 【免费下载链接】Arduino-For-Keil A lightweight Arduino framework for Keil projects. 项目地址: https://gitcode.com/gh_mirrors/ar/Arduino-For-Keil 你是否曾经在Arduino的易用性和STM32的强大性…

作者头像 李华
网站建设 2026/6/2 1:30:00

【CGLIB】在微服务或 RPC 框架中,CGLIB 可以用于哪些环节(如客户端 stub 生成)?

在微服务或 RPC 框架中,CGLIB 可以用于哪些环节(如客户端 stub 生成)? 问题引入 用户问题原文:在微服务或 RPC 框架中,CGLIB 可以用于哪些环节(如客户端 stub 生成)? 在构建超大规模分布式系统时,RPC(远程过程调用)是服务间通信的基石。一个优秀的 RPC 框架不仅要…

作者头像 李华
网站建设 2026/6/2 1:25:57

2026年实用降AIGC工具:亲测AI率从90%降至4%的稳妥方案

一、前言&#xff1a;2026年毕业必过AIGC检测门槛 2026年国内高校对学术论文的AIGC疑似度审核全面收紧&#xff0c;绝大多数院校都发布了明确的AIGC检测数值要求&#xff1a;985、211院校规定本科论文AI率需低于20%&#xff0c;硕士论文AI率不得高于15%&#xff0c;普通高校也普…

作者头像 李华
网站建设 2026/6/2 1:19:07

EarlyStopping调参避坑指南:你的patience和min_delta真的设对了吗?

EarlyStopping调参避坑指南&#xff1a;你的patience和min_delta真的设对了吗&#xff1f;在时序预测模型的训练过程中&#xff0c;许多数据科学家都遇到过这样的困扰&#xff1a;明明设置了EarlyStopping回调函数&#xff0c;模型却要么过早停止训练导致欠拟合&#xff0c;要么…

作者头像 李华
网站建设 2026/6/2 1:15:25

力扣HOT100(48)图论-腐烂的橘子

为什么必须用「多源 BFS」&#xff1f;先想&#xff1a;如果只有一个腐烂橘子&#xff0c;怎么做&#xff1f;这就是普通的单源 BFS&#xff1a;把初始腐烂橘子入队&#xff08;第 0 层&#xff09;每分钟处理队列里当前层的所有橘子&#xff0c;把它们相邻的新鲜橘子腐烂&…

作者头像 李华