376 lines
15 KiB
Python
376 lines
15 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
"""
|
|
人工智能宣讲会海报生成器
|
|
Artificial Intelligence Seminar Poster Generator
|
|
|
|
一个功能丰富的海报生成工具,支持多种设计风格、动画效果和交互功能。
|
|
Author: AI Assistant
|
|
Version: 1.0.0
|
|
"""
|
|
|
|
import tkinter as tk
|
|
from tkinter import ttk, messagebox, filedialog
|
|
import math
|
|
import random
|
|
import time
|
|
from datetime import datetime, timedelta
|
|
import json
|
|
import os
|
|
from PIL import Image, ImageDraw, ImageFont, ImageTk, ImageFilter
|
|
import numpy as np
|
|
from typing import List, Tuple, Dict, Optional
|
|
import threading
|
|
|
|
class AIPosterGenerator:
|
|
"""AI宣讲会海报生成器主类"""
|
|
|
|
def __init__(self):
|
|
self.root = tk.Tk()
|
|
self.root.title("人工智能宣讲会海报生成器")
|
|
self.root.geometry("1400x900")
|
|
self.root.configure(bg='#f0f0f0')
|
|
|
|
# 海报配置
|
|
self.poster_width = 800
|
|
self.poster_height = 1000
|
|
self.current_theme = "tech_blue"
|
|
|
|
# 颜色主题配置
|
|
self.themes = {
|
|
"tech_blue": {
|
|
"bg_primary": "#1a1a2e",
|
|
"bg_secondary": "#16213e",
|
|
"accent": "#0f3460",
|
|
"highlight": "#e94560",
|
|
"text_primary": "#ffffff",
|
|
"text_secondary": "#b8b8b8",
|
|
"gradient_start": "#667eea",
|
|
"gradient_end": "#764ba2"
|
|
},
|
|
"future_purple": {
|
|
"bg_primary": "#2d1b69",
|
|
"bg_secondary": "#11998e",
|
|
"accent": "#38ef7d",
|
|
"highlight": "#fc466b",
|
|
"text_primary": "#ffffff",
|
|
"text_secondary": "#e0e0e0",
|
|
"gradient_start": "#667eea",
|
|
"gradient_end": "#764ba2"
|
|
},
|
|
"neon_cyber": {
|
|
"bg_primary": "#000000",
|
|
"bg_secondary": "#1a0033",
|
|
"accent": "#00ff41",
|
|
"highlight": "#ff073a",
|
|
"text_primary": "#00ffff",
|
|
"text_secondary": "#ff6b6b",
|
|
"gradient_start": "#ff006e",
|
|
"gradient_end": "#8338ec"
|
|
},
|
|
"golden_sunset": {
|
|
"bg_primary": "#ff6b6b",
|
|
"bg_secondary": "#feca57",
|
|
"accent": "#ff9ff3",
|
|
"highlight": "#54a0ff",
|
|
"text_primary": "#2c2c54",
|
|
"text_secondary": "#40407a",
|
|
"gradient_start": "#ff9a9e",
|
|
"gradient_end": "#fecfef"
|
|
}
|
|
}
|
|
|
|
# 宣讲会信息
|
|
self.seminar_info = {
|
|
"title": "人工智能:重塑未来的力量",
|
|
"subtitle": "Artificial Intelligence: Shaping the Future",
|
|
"date": "2024年1月15日",
|
|
"time": "14:00-17:00",
|
|
"venue": "科技大厦国际会议中心",
|
|
"speakers": [
|
|
{"name": "张教授", "title": "AI研究院院长", "topic": "深度学习的前沿进展"},
|
|
{"name": "李博士", "title": "机器学习专家", "topic": "GPT技术与应用"},
|
|
{"name": "王工程师", "title": "算法架构师", "topic": "AI在各行业的实践"}
|
|
],
|
|
"organizers": ["人工智能学会", "科技创新协会", "未来科技论坛"],
|
|
"contact": "电话: 400-123-4567 | 邮箱: ai@seminar.com",
|
|
"qr_code_text": "扫码报名 | 名额有限"
|
|
}
|
|
|
|
# 动画粒子系统
|
|
self.particles = []
|
|
self.animation_running = False
|
|
self.neural_network_nodes = []
|
|
self.neural_network_connections = []
|
|
|
|
self.setup_ui()
|
|
self.initialize_neural_network()
|
|
self.create_particles()
|
|
|
|
def setup_ui(self):
|
|
"""设置用户界面"""
|
|
# 主框架
|
|
main_frame = tk.Frame(self.root, bg='#f0f0f0')
|
|
main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
|
|
|
|
# 左侧控制面板
|
|
control_frame = tk.Frame(main_frame, bg='white', relief=tk.RAISED, bd=2)
|
|
control_frame.pack(side=tk.LEFT, fill=tk.Y, padx=(0, 10))
|
|
|
|
# 标题
|
|
title_label = tk.Label(control_frame, text="海报生成器控制台",
|
|
font=("Arial", 16, "bold"), bg='white')
|
|
title_label.pack(pady=10)
|
|
|
|
# 主题选择
|
|
theme_frame = tk.LabelFrame(control_frame, text="选择主题", bg='white', padx=10, pady=10)
|
|
theme_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
|
|
for theme in self.themes.keys():
|
|
rb = tk.Radiobutton(theme_frame, text=theme.replace("_", " ").title(),
|
|
variable=tk.StringVar(value=self.current_theme),
|
|
value=theme, command=lambda t=theme: self.change_theme(t),
|
|
bg='white')
|
|
rb.pack(anchor=tk.W)
|
|
|
|
# 信息编辑
|
|
info_frame = tk.LabelFrame(control_frame, text="宣讲会信息", bg='white', padx=10, pady=10)
|
|
info_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
|
|
# 标题编辑
|
|
tk.Label(info_frame, text="主标题:", bg='white').grid(row=0, column=0, sticky=tk.W)
|
|
self.title_entry = tk.Entry(info_frame, width=30)
|
|
self.title_entry.insert(0, self.seminar_info["title"])
|
|
self.title_entry.grid(row=0, column=1, padx=5, pady=2)
|
|
|
|
# 日期编辑
|
|
tk.Label(info_frame, text="日期:", bg='white').grid(row=1, column=0, sticky=tk.W)
|
|
self.date_entry = tk.Entry(info_frame, width=30)
|
|
self.date_entry.insert(0, self.seminar_info["date"])
|
|
self.date_entry.grid(row=1, column=1, padx=5, pady=2)
|
|
|
|
# 时间编辑
|
|
tk.Label(info_frame, text="时间:", bg='white').grid(row=2, column=0, sticky=tk.W)
|
|
self.time_entry = tk.Entry(info_frame, width=30)
|
|
self.time_entry.insert(0, self.seminar_info["time"])
|
|
self.time_entry.grid(row=2, column=1, padx=5, pady=2)
|
|
|
|
# 地点编辑
|
|
tk.Label(info_frame, text="地点:", bg='white').grid(row=3, column=0, sticky=tk.W)
|
|
self.venue_entry = tk.Entry(info_frame, width=30)
|
|
self.venue_entry.insert(0, self.seminar_info["venue"])
|
|
self.venue_entry.grid(row=3, column=1, padx=5, pady=2)
|
|
|
|
# 动画控制
|
|
animation_frame = tk.LabelFrame(control_frame, text="动画效果", bg='white', padx=10, pady=10)
|
|
animation_frame.pack(fill=tk.X, padx=10, pady=5)
|
|
|
|
self.animation_btn = tk.Button(animation_frame, text="启动动画",
|
|
command=self.toggle_animation,
|
|
bg='#4CAF50', fg='white', width=15)
|
|
self.animation_btn.pack(pady=5)
|
|
|
|
# 粒子效果
|
|
self.particles_btn = tk.Button(animation_frame, text="粒子效果",
|
|
command=self.toggle_particles,
|
|
bg='#2196F3', fg='white', width=15)
|
|
self.particles_btn.pack(pady=5)
|
|
|
|
# 神经网络动画
|
|
self.neural_btn = tk.Button(animation_frame, text="神经网络",
|
|
command=self.toggle_neural_network,
|
|
bg='#9C27B0', fg='white', width=15)
|
|
self.neural_btn.pack(pady=5)
|
|
|
|
# 操作按钮
|
|
button_frame = tk.Frame(control_frame, bg='white')
|
|
button_frame.pack(fill=tk.X, padx=10, pady=10)
|
|
|
|
self.generate_btn = tk.Button(button_frame, text="生成海报",
|
|
command=self.generate_poster,
|
|
bg='#FF9800', fg='white', width=15, height=2)
|
|
self.generate_btn.pack(pady=5)
|
|
|
|
self.preview_btn = tk.Button(button_frame, text="预览海报",
|
|
command=self.preview_poster,
|
|
bg='#00BCD4', fg='white', width=15, height=2)
|
|
self.preview_btn.pack(pady=5)
|
|
|
|
self.save_btn = tk.Button(button_frame, text="保存海报",
|
|
command=self.save_poster,
|
|
bg='#4CAF50', fg='white', width=15, height=2)
|
|
self.save_btn.pack(pady=5)
|
|
|
|
# 右侧海报显示区域
|
|
self.poster_frame = tk.Frame(main_frame, bg='white', relief=tk.SUNKEN, bd=3)
|
|
self.poster_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
|
|
|
|
# 海报画布
|
|
self.poster_canvas = tk.Canvas(self.poster_frame,
|
|
width=self.poster_width,
|
|
height=self.poster_height,
|
|
bg='white', relief=tk.RAISED, bd=2)
|
|
self.poster_canvas.pack(pady=20)
|
|
|
|
# 状态栏
|
|
self.status_bar = tk.Label(self.root, text="就绪", bd=1, relief=tk.SUNKEN, anchor=tk.W)
|
|
self.status_bar.pack(side=tk.BOTTOM, fill=tk.X)
|
|
|
|
def change_theme(self, theme_name):
|
|
"""更改主题"""
|
|
self.current_theme = theme_name
|
|
self.update_status(f"主题已切换至: {theme_name.replace('_', ' ').title()}")
|
|
|
|
def create_particles(self):
|
|
"""创建粒子系统"""
|
|
for _ in range(50):
|
|
particle = {
|
|
'x': random.randint(0, self.poster_width),
|
|
'y': random.randint(0, self.poster_height),
|
|
'vx': random.uniform(-2, 2),
|
|
'vy': random.uniform(-2, 2),
|
|
'size': random.randint(2, 6),
|
|
'color': random.choice(['#ffffff', '#00ffff', '#ff00ff', '#ffff00']),
|
|
'life': random.randint(100, 200)
|
|
}
|
|
self.particles.append(particle)
|
|
|
|
def initialize_neural_network(self):
|
|
"""初始化神经网络节点和连接"""
|
|
# 创建网络节点
|
|
layers = [3, 5, 4, 2] # 每层节点数
|
|
layer_width = self.poster_width // (len(layers) + 1)
|
|
|
|
for i, layer_size in enumerate(layers):
|
|
x = (i + 1) * layer_width
|
|
layer_nodes = []
|
|
|
|
for j in range(layer_size):
|
|
y = (j + 1) * (self.poster_height // (layer_size + 1))
|
|
node = {
|
|
'x': x,
|
|
'y': y,
|
|
'activation': random.random(),
|
|
'bias': random.uniform(-1, 1)
|
|
}
|
|
layer_nodes.append(node)
|
|
|
|
self.neural_network_nodes.append(layer_nodes)
|
|
|
|
# 创建连接
|
|
for i in range(len(self.neural_network_nodes) - 1):
|
|
for node1 in self.neural_network_nodes[i]:
|
|
for node2 in self.neural_network_nodes[i + 1]:
|
|
connection = {
|
|
'from': node1,
|
|
'to': node2,
|
|
'weight': random.uniform(-1, 1),
|
|
'active': random.choice([True, False])
|
|
}
|
|
self.neural_network_connections.append(connection)
|
|
|
|
def toggle_animation(self):
|
|
"""切换动画状态"""
|
|
if not self.animation_running:
|
|
self.animation_running = True
|
|
self.animation_btn.config(text="停止动画", bg='#f44336')
|
|
self.animate()
|
|
self.update_status("动画已启动")
|
|
else:
|
|
self.animation_running = False
|
|
self.animation_btn.config(text="启动动画", bg='#4CAF50')
|
|
self.update_status("动画已停止")
|
|
|
|
def toggle_particles(self):
|
|
"""切换粒子效果"""
|
|
if hasattr(self, 'particles_animation') and self.particles_animation:
|
|
self.particles_animation = False
|
|
self.particles_btn.config(text="粒子效果", bg='#2196F3')
|
|
else:
|
|
self.particles_animation = True
|
|
self.particles_btn.config(text="停止粒子", bg='#f44336')
|
|
self.animate_particles()
|
|
|
|
def toggle_neural_network(self):
|
|
"""切换神经网络动画"""
|
|
if hasattr(self, 'neural_animation') and self.neural_animation:
|
|
self.neural_animation = False
|
|
self.neural_btn.config(text="神经网络", bg='#9C27B0')
|
|
else:
|
|
self.neural_animation = True
|
|
self.neural_btn.config(text="停止网络", bg='#f44336')
|
|
self.animate_neural_network()
|
|
|
|
def animate(self):
|
|
"""主动画循环"""
|
|
if self.animation_running:
|
|
# 更新粒子位置
|
|
for particle in self.particles:
|
|
particle['x'] += particle['vx']
|
|
particle['y'] += particle['vy']
|
|
particle['life'] -= 1
|
|
|
|
# 边界检测
|
|
if particle['x'] < 0 or particle['x'] > self.poster_width:
|
|
particle['vx'] *= -1
|
|
if particle['y'] < 0 or particle['y'] > self.poster_height:
|
|
particle['vy'] *= -1
|
|
|
|
# 重生粒子
|
|
if particle['life'] <= 0:
|
|
particle['x'] = random.randint(0, self.poster_width)
|
|
particle['y'] = random.randint(0, self.poster_height)
|
|
particle['life'] = random.randint(100, 200)
|
|
|
|
# 重绘画布
|
|
self.preview_poster()
|
|
|
|
# 继续动画
|
|
self.root.after(50, self.animate)
|
|
|
|
def animate_particles(self):
|
|
"""粒子动画"""
|
|
if hasattr(self, 'particles_animation') and self.particles_animation:
|
|
# 更新粒子
|
|
for particle in self.particles:
|
|
particle['x'] += particle['vx'] * 0.5
|
|
particle['y'] += particle['vy'] * 0.5
|
|
|
|
# 边界反弹
|
|
if particle['x'] < 0 or particle['x'] > self.poster_width:
|
|
particle['vx'] *= -1
|
|
if particle['y'] < 0 or particle['y'] > self.poster_height:
|
|
particle['vy'] *= -1
|
|
|
|
# 重绘
|
|
self.preview_poster()
|
|
self.root.after(100, self.animate_particles)
|
|
|
|
def animate_neural_network(self):
|
|
"""神经网络动画"""
|
|
if hasattr(self, 'neural_animation') and self.neural_animation:
|
|
# 更新节点激活值
|
|
for layer in self.neural_network_nodes:
|
|
for node in layer:
|
|
node['activation'] = random.random()
|
|
|
|
# 更新连接状态
|
|
for connection in self.neural_network_connections:
|
|
connection['active'] = random.choice([True, False])
|
|
if connection['active']:
|
|
connection['weight'] = random.uniform(0.5, 1.0)
|
|
else:
|
|
connection['weight'] = random.uniform(0, 0.3)
|
|
|
|
# 重绘
|
|
self.preview_poster()
|
|
self.root.after(200, self.animate_neural_network)
|
|
|
|
def update_seminar_info(self):
|
|
"""更新宣讲会信息"""
|
|
self.seminar_info["title"] = self.title_entry.get()
|
|
self.seminar_info["date"] = self.date_entry.get()
|
|
self.seminar_info["time"] = self.time_entry.get()
|
|
self.seminar_info["venue"] = self.venue_entry.get()
|
|
|
|
def generate_gradient_background(self, draw, width |