#!/usr/bin/env python3 """生成精美通知卡片""" from PIL import Image, ImageDraw, ImageFont from io import BytesIO def create_card(): W, H = 600, 320 # 创建画布 img = Image.new('RGBA', (W, H), (0, 0, 0, 0)) draw = ImageDraw.Draw(img) # ==================== 卡片背景 ==================== # 主背景 - 柔和蓝渐变 for y in range(H): ratio = y / H r = int(30 + (60 - 30) * ratio) g = int(100 + (160 - 100) * ratio) b = int(200 + (220 - 200) * ratio) draw.line([(0, y), (W, y)], fill=(r, g, b, 255)) # 卡片主体圆角 card_x, card_y = 10, 10 card_w, card_h = W - 20, H - 20 # 绘制圆角矩形作为底板 draw.rounded_rectangle( [card_x, card_y, card_x + card_w, card_y + card_h], radius=20, fill=(255, 255, 255, 240) ) # ==================== 顶部装饰 ==================== # 装饰线条 draw.line([(card_x + 20, card_y + 20), (card_x + card_w - 20, card_y + 20)], fill=(7, 193, 96, 200), width=3) # ==================== 图标区域 ==================== # 时钟图标(圆形背景) icon_x, icon_y = 60, 70 draw.ellipse([icon_x - 25, icon_y - 25, icon_x + 25, icon_y + 25], fill=(7, 193, 96, 30)) draw.ellipse([icon_x - 20, icon_y - 20, icon_x + 20, icon_y + 20], outline=(7, 193, 96, 255), width=2) # 时针 draw.line([icon_x, icon_y, icon_x, icon_y - 10], fill=(7, 193, 96, 255), width=2) # 分针 draw.line([icon_x, icon_y, icon_x + 8, icon_y + 5], fill=(7, 193, 96, 255), width=2) # 中心点 draw.ellipse([icon_x - 2, icon_y - 2, icon_x + 2, icon_y + 2], fill=(7, 193, 96, 255)) # ==================== 标题文字 ==================== try: title_font = ImageFont.truetype("C:/Windows/Fonts/msyh.ttc", 28) subtitle_font = ImageFont.truetype("C:/Windows/Fonts/msyh.ttc", 16) btn_font = ImageFont.truetype("C:/Windows/Fonts/msyh.ttc", 20) except: try: title_font = ImageFont.truetype("C:/Windows/Fonts/simhei.ttf", 28) subtitle_font = ImageFont.truetype("C:/Windows/Fonts/simhei.ttf", 16) btn_font = ImageFont.truetype("C:/Windows/Fonts/simhei.ttf", 20) except: title_font = ImageFont.load_default() subtitle_font = ImageFont.load_default() btn_font = ImageFont.load_default() # 主标题 title = "IT咨询即将关闭" draw.text((100, 55), title, fill=(40, 40, 40), font=title_font) # 副标题 subtitle = "请尽快回复坐席,否则咨询将自动结束" draw.text((100, 95), subtitle, fill=(120, 120, 120), font=subtitle_font) # ==================== 3D水晶按钮 ==================== btn_x, btn_y = 40, 150 btn_w, btn_h = 520, 60 btn_radius = 15 # 按钮阴影 draw.rounded_rectangle( [btn_x + 4, btn_y + 4, btn_x + btn_w + 4, btn_y + btn_h + 4], radius=btn_radius, fill=(0, 0, 0, 40) ) # 按钮主体 - 渐变 for i in range(btn_h): ratio = i / btn_h # 绿色渐变 r = int(7 + (20 - 7) * ratio) g = int(193 + (180 - 193) * ratio) b = int(96 + (60 - 96) * ratio) draw.rectangle([btn_x, btn_y + i, btn_x + btn_w, btn_y + i + 1], fill=(r, g, b)) # 按钮顶部高光 draw.rounded_rectangle( [btn_x, btn_y, btn_x + btn_w, btn_y + btn_h // 2], radius=btn_radius, fill=(255, 255, 255, 40) ) # 按钮边框 draw.rounded_rectangle( [btn_x, btn_y, btn_x + btn_w, btn_y + btn_h], radius=btn_radius, outline=(5, 150, 70, 100), width=1 ) # 按钮文字 btn_text = "立即回复" # 计算文字居中 bbox = draw.textbbox((0, 0), btn_text, font=btn_font) text_w = bbox[2] - bbox[0] text_x = btn_x + (btn_w - text_w) // 2 text_y = btn_y + (btn_h - (bbox[3] - bbox[1])) // 2 - 2 draw.text((text_x, text_y), btn_text, fill=(255, 255, 255), font=btn_font) # ==================== 底部提示 ==================== tip = "点击卡片直接跳转到咨询页面" draw.text((card_x + 20, card_y + card_h - 30), tip, fill=(150, 150, 150), font=subtitle_font) # 保存 buffer = BytesIO() img.save(buffer, format='PNG') buffer.seek(0) return buffer.getvalue() # 本地测试 if __name__ == "__main__": data = create_card() with open("D:/资料/03-项目开发/wecom_it_smart_desk/deploy-server/it_reminder_card_v2.png", "wb") as f: f.write(data) print("✅ 卡片已保存")