Z-Image-Turbo-rinaiqiao-huiyewunv保姆级教学:Streamlit会话状态保存生成历史记录

张开发
2026/4/27 15:24:17 15 分钟阅读

分享文章

Z-Image-Turbo-rinaiqiao-huiyewunv保姆级教学:Streamlit会话状态保存生成历史记录
Z-Image-Turbo-rinaiqiao-huiyewunv保姆级教学Streamlit会话状态保存生成历史记录你是不是也遇到过这样的情况用AI画图工具生成了好几张特别满意的二次元人物图结果刷新一下页面或者不小心关掉了浏览器刚才那些精美的作品就全都不见了只能对着空白的界面干瞪眼。今天我要给你介绍一个能彻底解决这个痛点的方案——给Z-Image Turbo辉夜大小姐绘图工具加上会话状态保存和生成历史记录功能。这不仅仅是加个功能那么简单而是让你的创作过程从“一次性体验”变成“可追溯、可管理、可复现”的完整工作流。1. 为什么你需要历史记录功能在深入代码之前我们先想想这个功能到底能帮你解决什么问题。痛点一灵感丢失你花了半小时调整提示词终于生成了一张完美的辉夜大小姐图片。然后你想微调一下背景结果不小心点了刷新刚才那张图就再也找不回来了。那种感觉就像写了一半的文档没保存一样难受。痛点二参数遗忘“刚才那张特别好看的图我到底用了什么提示词来着”没有历史记录你只能靠记忆去回想那些复杂的参数组合成功率几乎为零。痛点三对比困难想看看不同CFG Scale值对画面风格的影响没有历史记录你只能生成一张看一张根本没法直观对比。我们的解决方案在原有的Z-Image Turbo工具基础上增加一个持久化的历史记录面板。每次生成的作品、使用的参数、生成时间都会自动保存即使关闭浏览器再打开历史记录依然存在。你还可以一键复用历史参数重新生成或者批量导出喜欢的作品。2. 环境准备与代码结构在开始改造之前确保你已经有了基础的Z-Image Turbo运行环境。如果你还没部署可以参考之前的教程先搭建起来。2.1 需要安装的额外依赖除了原有的streamlit、torch、transformers等我们还需要一个轻量级的数据库来存储历史记录。这里我选择tinydb因为它足够简单不需要配置数据库服务器。pip install tinydb2.2 项目文件结构规划为了让代码更清晰我建议这样组织你的项目文件z-image-turbo-history/ ├── app.py # 主程序文件 ├── history_db.json # TinyDB自动生成的数据库文件 ├── generated_images/ # 保存生成图片的文件夹 │ ├── 20240515_143022_1.png │ ├── 20240515_143125_2.png │ └── ... └── requirements.txt # 依赖列表关键点说明history_db.json会自动创建不需要手动处理generated_images/文件夹需要提前创建好图片按时间戳命名避免重复3. 核心功能实现详解现在我们来一步步实现历史记录功能。我会把完整的代码拆解成几个关键部分让你能清楚理解每一块的作用。3.1 数据库初始化与历史记录模型首先我们需要定义历史记录的数据结构并初始化数据库连接。# app.py import streamlit as st from tinydb import TinyDB, Query from datetime import datetime import os import json # 初始化数据库 def init_database(): 初始化TinyDB数据库 db_path history_db.json db TinyDB(db_path) return db # 历史记录数据结构 class GenerationRecord: 生成记录数据类 def __init__(self, prompt, negative_prompt, steps, cfg_scale, seed, image_filename, timestampNone): self.prompt prompt self.negative_prompt negative_prompt self.steps steps self.cfg_scale cfg_scale self.seed seed self.image_filename image_filename self.timestamp timestamp or datetime.now().strftime(%Y-%m-%d %H:%M:%S) def to_dict(self): 转换为字典格式便于存储 return { prompt: self.prompt, negative_prompt: self.negative_prompt, steps: self.steps, cfg_scale: self.cfg_scale, seed: self.seed, image_filename: self.image_filename, timestamp: self.timestamp }代码解读TinyDB是一个轻量级的文档数据库数据以JSON格式存储GenerationRecord类定义了每条历史记录包含哪些信息to_dict()方法把对象转换成字典方便存入数据库时间戳自动生成格式为年-月-日 时:分:秒3.2 Streamlit会话状态管理Streamlit有个很重要的特性每次用户交互都会重新运行整个脚本。为了在多次运行间保持数据我们需要使用st.session_state。# 初始化会话状态 def init_session_state(): 初始化Streamlit会话状态 if db not in st.session_state: st.session_state.db init_database() if history not in st.session_state: # 从数据库加载历史记录 st.session_state.history load_history_records() if current_page not in st.session_state: st.session_state.current_page 0 if selected_record not in st.session_state: st.session_state.selected_record None def load_history_records(): 从数据库加载所有历史记录 db st.session_state.db records db.all() # 按时间倒序排列最新的在前面 records.sort(keylambda x: x[timestamp], reverseTrue) return records关键技巧st.session_state是Streamlit提供的状态管理工具我们把数据库连接和历史记录都放在会话状态中避免重复初始化历史记录按时间倒序排列这样最新的作品总是显示在最前面3.3 图片保存与记录存储每次生成图片后我们不仅要显示还要保存到本地并记录到数据库。import uuid from PIL import Image def save_generated_image(image, prompt): 保存生成的图片到本地 # 创建图片保存目录如果不存在 os.makedirs(generated_images, exist_okTrue) # 生成唯一文件名时间戳 UUID 提示词前10个字符 timestamp datetime.now().strftime(%Y%m%d_%H%M%S) unique_id str(uuid.uuid4())[:8] prompt_prefix prompt[:20].replace( , _).replace(/, _) filename f{timestamp}_{unique_id}_{prompt_prefix}.png filepath os.path.join(generated_images, filename) # 保存图片 if isinstance(image, Image.Image): image.save(filepath, PNG) else: # 如果是numpy数组或其他格式先转换 from PIL import Image if hasattr(image, cpu): image image.cpu() if hasattr(image, numpy): image image.numpy() if image.shape[0] 3: # CHW格式 image image.transpose(1, 2, 0) image (image * 255).astype(uint8) Image.fromarray(image).save(filepath, PNG) return filename def add_to_history(prompt, negative_prompt, steps, cfg_scale, seed, image_filename): 添加生成记录到历史数据库 record GenerationRecord( promptprompt, negative_promptnegative_prompt, stepssteps, cfg_scalecfg_scale, seedseed, image_filenameimage_filename ) # 添加到数据库 db st.session_state.db record_id db.insert(record.to_dict()) # 更新会话状态中的历史记录 st.session_state.history.insert(0, record.to_dict()) # 限制历史记录数量避免数据库过大 if len(st.session_state.history) 100: # 删除最老的记录数据库和会话状态都删除 oldest_records db.all() oldest_records.sort(keylambda x: x[timestamp]) for old_record in oldest_records[:-100]: db.remove(doc_ids[old_record.doc_id]) st.session_state.history st.session_state.history[:100] return record_id实用功能文件名包含时间戳、UUID和提示词片段既唯一又有意义自动创建保存目录避免文件找不到的错误限制历史记录为100条防止数据库无限增长支持多种图片格式PIL.Image、numpy数组、torch tensor3.4 历史记录面板UI设计历史记录不仅要能存还要好看好用。我们来设计一个直观的展示面板。def display_history_panel(): 显示历史记录面板 st.sidebar.markdown(---) st.sidebar.subheader( 生成历史记录) if not st.session_state.history: st.sidebar.info(暂无生成记录开始创作吧) return # 分页显示 records_per_page 5 total_pages max(1, (len(st.session_state.history) records_per_page - 1) // records_per_page) # 分页控件 col1, col2, col3 st.sidebar.columns([1, 2, 1]) with col1: if st.button(◀, keyprev_page): if st.session_state.current_page 0: st.session_state.current_page - 1 with col2: st.markdown(f**第 {st.session_state.current_page 1} / {total_pages} 页**) with col3: if st.button(▶, keynext_page): if st.session_state.current_page total_pages - 1: st.session_state.current_page 1 # 显示当前页的记录 start_idx st.session_state.current_page * records_per_page end_idx min(start_idx records_per_page, len(st.session_state.history)) for i in range(start_idx, end_idx): record st.session_state.history[i] with st.sidebar.expander(f{record[timestamp]}, expandedFalse): # 显示缩略图 image_path os.path.join(generated_images, record[image_filename]) if os.path.exists(image_path): try: image Image.open(image_path) # 创建缩略图 image.thumbnail((200, 200)) st.image(image, use_column_widthTrue) except: st.warning(图片加载失败) # 显示参数 st.caption(f**提示词:** {record[prompt][:50]}...) st.caption(f**步数:** {record[steps]} | **CFG:** {record[cfg_scale]} | **Seed:** {record[seed]}) # 操作按钮 col1, col2 st.columns(2) with col1: if st.button(复用参数, keyfreuse_{i}): st.session_state.selected_record record # 这里会触发主界面的参数填充 with col2: if st.button(删除, keyfdelete_{i}): delete_history_record(record) st.rerun() def delete_history_record(record): 删除历史记录 db st.session_state.db History Query() # 从数据库删除 db.remove(History.timestamp record[timestamp]) # 从会话状态删除 st.session_state.history [r for r in st.session_state.history if r[timestamp] ! record[timestamp]] # 删除图片文件可选 # image_path os.path.join(generated_images, record[image_filename]) # if os.path.exists(image_path): # os.remove(image_path) st.success(记录已删除)UI设计亮点使用侧边栏展示历史记录不占用主创作区域分页显示避免历史记录过多导致界面卡顿可展开的折叠面板节省空间缩略图预览直观看到作品一键复用参数快速重新生成删除功能管理历史记录4. 与原有绘图功能的集成现在我们需要把历史记录功能集成到原有的Z-Image Turbo绘图工具中。主要修改两个地方生成后的保存逻辑和参数复用功能。4.1 修改生成函数找到你原来的图片生成函数在生成成功后添加保存和记录逻辑。def generate_image_with_history(): 生成图片并保存到历史记录 # 获取用户输入的参数这部分是你原有的代码 prompt st.session_state.get(prompt_input, ) negative_prompt st.session_state.get(negative_input, ) steps st.session_state.get(steps_slider, 20) cfg_scale st.session_state.get(cfg_slider, 2.0) seed st.session_state.get(seed_input, -1) # 调用原有的生成函数这里需要替换成你的实际生成代码 try: with st.spinner( 画师正在奋笔疾书中...): # 这里是你的图片生成代码 # generated_image pipeline(promptprompt, ...).images[0] generated_image generate_image(prompt, negative_prompt, steps, cfg_scale, seed) # 保存图片到本地 image_filename save_generated_image(generated_image, prompt) # 添加到历史记录 add_to_history(prompt, negative_prompt, steps, cfg_scale, seed, image_filename) # 显示生成的图片 st.image(generated_image, caption生成结果, use_column_widthTrue) st.success(f图片已生成并保存到历史记录) # 显示图片保存路径 st.info(f图片文件: generated_images/{image_filename}) except Exception as e: st.error(f生成失败: {str(e)})4.2 添加参数复用功能当用户点击历史记录中的复用参数按钮时自动填充主界面的参数。def setup_parameter_inputs(): 设置参数输入界面支持从历史记录填充 # 检查是否有选中的历史记录 if st.session_state.selected_record: record st.session_state.selected_record default_prompt record[prompt] default_negative record[negative_prompt] default_steps record[steps] default_cfg record[cfg_scale] default_seed record[seed] # 显示提示信息 st.info(f已从历史记录加载参数生成于 {record[timestamp]}) # 清空选中状态避免下次自动加载 st.session_state.selected_record None else: # 默认值 default_prompt 辉夜大小姐红色瞳孔黑色长发校服二次元风格高清细节丰富 default_negative 低质量模糊NSFW畸形多余的手指 default_steps 20 default_cfg 2.0 default_seed -1 # 参数输入控件 with st.container(): st.subheader( 绘图参数设置) col1, col2 st.columns(2) with col1: prompt st.text_area( 提示词 (Prompt), valuedefault_prompt, height100, keyprompt_input, help描述你想要生成的画面内容 ) negative_prompt st.text_area( 负面提示 (Negative Prompt), valuedefault_negative, height80, keynegative_input, help描述你不希望在画面中出现的内容 ) with col2: steps st.slider( 生成步数 (Steps), min_value4, max_value30, valuedefault_steps, step1, keysteps_slider, helpTurbo模型推荐20步左右步数越高细节越丰富但速度越慢 ) cfg_scale st.slider( 提示词强度 (CFG Scale), min_value1.0, max_value5.0, valuedefault_cfg, step0.5, keycfg_slider, help控制提示词对生成结果的影响程度推荐2.0 ) seed st.number_input( 随机种子 (Seed), valuedefault_seed, keyseed_input, help-1表示随机种子固定种子可以复现相同结果 ) return prompt, negative_prompt, steps, cfg_scale, seed5. 完整应用整合现在我们把所有功能整合到一起创建一个完整的带历史记录的绘图应用。# app.py 完整主程序 import streamlit as st from tinydb import TinyDB, Query from datetime import datetime import os from PIL import Image import uuid # 初始化函数前面已经定义过 def init_database(): # ... 数据库初始化代码 def init_session_state(): # ... 会话状态初始化代码 def save_generated_image(image, prompt): # ... 图片保存代码 def add_to_history(prompt, negative_prompt, steps, cfg_scale, seed, image_filename): # ... 历史记录添加代码 def display_history_panel(): # ... 历史记录显示代码 def setup_parameter_inputs(): # ... 参数输入设置代码 def generate_image_with_history(): # ... 生成图片并保存代码 # 主函数 def main(): # 页面配置 st.set_page_config( page_titleZ-Image Turbo 辉夜大小姐绘图工具带历史记录, page_icon, layoutwide, initial_sidebar_stateexpanded ) # 初始化 init_session_state() # 标题和介绍 st.title( Z-Image Turbo 辉夜大小姐绘图工具) st.markdown( 基于 Tongyi-MAI Z-Image 底座模型开发的专属二次元人物绘图工具注入辉夜大小姐日奈娇微调权重。 **新增功能**自动保存生成历史支持参数复用和作品管理 ) # 主界面布局 col_main, col_sidebar st.columns([3, 1]) with col_main: # 等待模型初始化你的原有代码 if model_loaded not in st.session_state: with st.spinner( 正在初始化二次元绘图引擎...): # 这里加载你的模型 # load_model() st.session_state.model_loaded True st.success(✅ 人物模型加载完成) # 参数设置区域 prompt, negative_prompt, steps, cfg_scale, seed setup_parameter_inputs() # 生成按钮 if st.button( 生成人物写真, typeprimary, use_container_widthTrue): generate_image_with_history() # 历史记录中的图片大图展示 if st.session_state.history: st.markdown(---) st.subheader( 历史作品预览) # 显示最近3张图片 cols st.columns(3) for idx, record in enumerate(st.session_state.history[:3]): image_path os.path.join(generated_images, record[image_filename]) if os.path.exists(image_path): with cols[idx]: st.image(image_path, use_column_widthTrue) st.caption(f{record[timestamp][:16]}) with col_sidebar: # 历史记录面板 display_history_panel() # 额外功能 st.markdown(---) st.subheader(⚙️ 工具设置) # 清空历史记录谨慎操作 if st.button(清空所有历史记录, typesecondary): if st.checkbox(我确认要清空所有历史记录): st.session_state.db.truncate() st.session_state.history [] st.rerun() # 导出历史记录 if st.button(导出历史记录为JSON): history_data st.session_state.history import json json_str json.dumps(history_data, ensure_asciiFalse, indent2) st.download_button( label下载JSON文件, datajson_str, file_namegeneration_history.json, mimeapplication/json ) if __name__ __main__: main()6. 实际使用技巧与优化建议功能做好了怎么用得更好这里有几个实用技巧。6.1 历史记录的智能管理历史记录多了也会乱我建议添加一些智能管理功能def search_history_by_keyword(keyword): 按关键词搜索历史记录 db st.session_state.db History Query() # 在提示词和负面提示中搜索 results db.search( (History.prompt.test(lambda x: keyword.lower() in x.lower())) | (History.negative_prompt.test(lambda x: keyword.lower() in x.lower())) ) return sorted(results, keylambda x: x[timestamp], reverseTrue) def filter_history_by_date(start_date, end_date): 按日期范围筛选历史记录 db st.session_state.db History Query() results db.search( (History.timestamp start_date.strftime(%Y-%m-%d)) (History.timestamp end_date.strftime(%Y-%m-%d 23:59:59)) ) return sorted(results, keylambda x: x[timestamp], reverseTrue)6.2 性能优化建议如果你的历史记录很多比如超过1000条可能需要考虑性能优化图片懒加载只在展开历史记录时才加载缩略图分页查询不要一次性加载所有记录定期清理自动删除30天前的记录使用数据库索引TinyDB支持索引加速查询6.3 数据备份与恢复历史记录很重要建议添加备份功能def backup_history(): 备份历史记录 import shutil import datetime backup_dir history_backups os.makedirs(backup_dir, exist_okTrue) timestamp datetime.datetime.now().strftime(%Y%m%d_%H%M%S) backup_file os.path.join(backup_dir, fhistory_backup_{timestamp}.json) # 复制数据库文件 shutil.copy2(history_db.json, backup_file) # 复制图片文件夹 backup_images_dir os.path.join(backup_dir, fimages_{timestamp}) if os.path.exists(generated_images): shutil.copytree(generated_images, backup_images_dir) return backup_file7. 总结通过给Z-Image Turbo辉夜大小姐绘图工具添加历史记录功能我们彻底解决了AI绘图过程中的几个核心痛点功能价值总结永不丢失的创作记录每次生成的作品和参数都自动保存随时可以回顾一键复现优秀作品看到喜欢的作品点击复用参数就能重新生成直观的作品管理缩略图预览、时间排序、关键词搜索管理起来得心应手数据持久化存储即使关闭浏览器、重启应用历史记录依然存在技术实现要点回顾使用TinyDB实现轻量级数据存储无需复杂数据库配置利用st.session_state管理应用状态保持数据一致性设计合理的文件命名规则避免冲突且易于识别实现分页显示和图片懒加载保证界面流畅性添加参数复用功能提升创作效率下一步可以探索的方向添加作品标签和分类功能实现作品分享链接生成添加批量导出和打印功能集成云存储实现多设备同步这个历史记录功能虽然看起来简单但它彻底改变了AI绘图工具的使用体验。从一次性玩具变成了专业创作工具让你可以系统地积累和优化自己的提示词技巧真正把AI绘图用出生产力。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

更多文章