
这次我们来看一个很有意思的AI应用项目——“好消息就该由你亲手刮开【B站AI创造公开赛】”。这个项目不是一个独立的软件或模型而是一个结合了AI图像生成与互动前端技术的创意玩法实现。它的核心思路是利用AI生成一张带有“刮刮乐”涂层效果的图片用户可以通过鼠标或手指在屏幕上“刮开”涂层最终揭示出由AI生成的、充满惊喜的“好消息”图片。对于开发者或技术爱好者来说这个项目的价值在于它清晰地展示了一条技术链路如何将Stable Diffusion等AI文生图能力无缝集成到一个具有强交互性的Web前端应用中并创造出新颖的用户体验。它不只是一个概念演示更提供了可复用的工程化思路。本文将重点拆解这个项目背后的技术栈、实现原理并提供一个从零开始的本地部署与复现指南。你会了解到如何准备AI绘画环境、如何搭建交互式前端、以及如何将两者对接最终在自己的电脑上跑起一个完整的“AI刮刮乐”应用。无论你是想学习AI应用集成还是寻找创意互动项目的灵感这篇文章都能提供直接的参考。1. 核心能力速览能力项说明项目类型AI创意互动应用AI生成 Web前端交互核心技术栈前端HTML5 Canvas JavaScript后端Python AI绘画模型如Stable Diffusion核心功能1. 后端调用AI模型根据随机或指定提示词生成“好消息”图片。2. 前端生成一张覆盖在结果图上的“刮刮乐”涂层。3. 用户通过鼠标/触摸手势刮开涂层逐步揭示底层AI生成的图片。硬件门槛主要取决于AI绘画部分。如需本地运行Stable Diffusion推荐至少6GB显存的NVIDIA显卡。纯CPU推理速度较慢。前端部分对硬件无要求。启动方式需分别启动后端AI服务和前端Web服务。后端通常为Python Flask/FastAPI服务前端为静态HTTP服务。接口能力后端需提供文生图API接口供前端调用以获取生成的图片。批量任务支持批量生成不同的“好消息”图片但交互为单次单图。适合场景技术演示、创意营销活动页面、学习AI与前端结合、社区互动玩法。2. 适用场景与使用边界这个项目适合谁前端开发者希望学习如何将Canvas交互与后端API结合创造游戏化体验。AI应用开发者关注如何将AI模型能力包装成趣味性、可交互的终端产品。创意策划或运营人员寻找一种新颖的、技术驱动的互动形式用于活动拉新、用户参与。技术学习者对全栈开发AI后端交互前端感兴趣想通过一个完整的小项目练手。能解决什么问题技术整合演示提供了一个将前沿AI能力AIGC与经典Web技术Canvas结合的具体案例。用户体验创新将静态的AI生图结果转化为一个具有参与感和悬念感的动态交互过程。降低创意门槛有了这套技术框架可以快速更换AI模型、提示词或前端皮肤衍生出各种“刮开有奖”类应用。不适合什么场景高并发生产环境若AI生图服务部署在本地无法承受大量同时请求。需要云端API或队列优化。对生成内容精确控制AI生成具有随机性“好消息”图片内容不可百分百精确预期不适合需要严格内容审核的场景。离线纯前端应用核心的图片生成依赖后端AI服务无法完全脱离网络和服务端运行。版权与合规边界AI生成内容生成的图片版权归属需注意取决于所使用的AI模型的开源协议。用于公开项目或商业用途前请仔细阅读模型许可证。内容安全需要在后端对AI模型的提示词Prompt进行必要的过滤和审查避免生成不当内容。用户隐私此应用一般无需收集用户数据但若涉及需遵守相关隐私政策。3. 环境准备与前置条件要完整复现这个项目你需要准备两个部分的环境AI绘画后端环境和Web前端开发环境。3.1 AI绘画后端环境这是项目的核心负责生成“好消息”图片。你可以选择以下任意一种方案方案A使用现有在线API最快无硬件门槛优点无需本地显卡部署简单。缺点可能产生费用依赖网络且无法深度定制。可选服务Replicate、Stability AI、国内各大云平台的AI绘画服务等。需要准备相应的API Key。方案B本地部署Stable Diffusion WebUI推荐学习操作系统Windows 10/11 Linux 或 macOSApple Silicon芯片体验更佳。Python3.10.x 版本。建议使用Miniconda或虚拟环境管理。显卡驱动NVIDIA显卡用户确保已安装最新CUDA驱动。显存推荐8GB或以上。6GB显存可运行基础模型但分辨率受限。磁盘空间至少准备15-20GB空间用于存放模型文件。关键组件Stable Diffusion WebUI (Automatic1111或Forge)这是最流行的本地部署方案自带Web界面和API。基础模型如SDXL 1.0或SD 1.5的各类变体从Civitai或Hugging Face下载。可选LoRA/ControlNet用于更精确控制风格或内容。3.2 Web前端开发环境这部分相对轻量主要处理交互逻辑。代码编辑器VS Code, WebStorm等。Node.js与npm用于管理前端依赖和启动本地开发服务器。安装LTS版本即可。现代浏览器Chrome, Edge, Firefox等用于测试Canvas交互。本地HTTP服务器可以使用Node的http-server、live-server或Python的http.server模块。4. 安装部署与启动方式我们将以“本地部署Stable Diffusion WebUI 自定义前端”作为示例路径。4.1 步骤一部署AI绘画后端Stable Diffusion WebUI获取WebUI源码# 使用 git 克隆仓库 git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git cd stable-diffusion-webui启动安装脚本Windows直接运行webui-user.bat。脚本会自动创建Python虚拟环境并安装依赖。Linux/macOS运行./webui.sh。首次运行会下载大量依赖和默认模型耗时较长请保持网络通畅。启用API模式WebUI默认以图形界面启动。为了供前端调用我们需要启用API。在启动命令中添加参数。修改webui-user.batWindows或webui-user.sh其他系统中的COMMANDLINE_ARGS变量# 在 webui-user.bat 中设置 set COMMANDLINE_ARGS--api --listen--api启用API--listen允许网络访问注意安全生产环境需配置防火墙。重新启动WebUI。成功启动后日志中会显示运行地址如http://127.0.0.1:7860。验证API在浏览器中访问http://127.0.0.1:7860/docs或http://127.0.0.1:7860/可以看到WebUI界面。API接口位于/sdapi/v1/txt2img等路径。4.2 步骤二准备前端“刮刮乐”项目前端部分通常是一个独立的HTML/JS项目。你需要创建一个项目目录例如scratch-card-ai。项目结构scratch-card-ai/ ├── index.html # 主页面 ├── style.css # 样式文件 ├── script.js # 核心交互逻辑 └── server.js # 可选的简易Node代理服务器用于解决跨域核心文件index.html!DOCTYPE html html langzh-CN head meta charsetUTF-8 meta nameviewport contentwidthdevice-width, initial-scale1.0 titleAI刮刮乐 - 好消息等你揭开/title link relstylesheet hrefstyle.css /head body div classcontainer h1 好消息就该由你亲手刮开/h1 p刮开下方涂层看看AI为你生成了什么惊喜/p div classcard-container !-- 画布用于显示最终图片 -- canvas idresultCanvas width512 height512/canvas !-- 画布用于覆盖涂层和交互 -- canvas idscratchCanvas width512 height512/canvas /div div classcontrols button idgenerateBtn生成新好消息/button button idresetBtn重置刮卡/button p提示词span idpromptText正在生成.../span/p /div div classstatus idstatus准备就绪/div /div script srcscript.js/script /body /html核心文件script.js (逻辑骨架)// 配置后端API地址 const API_BASE_URL http://127.0.0.1:7860; const TXT2IMG_API ${API_BASE_URL}/sdapi/v1/txt2img; // 获取DOM元素 const resultCanvas document.getElementById(resultCanvas); const scratchCanvas document.getElementById(scratchCanvas); const generateBtn document.getElementById(generateBtn); const resetBtn document.getElementById(resetBtn); const promptText document.getElementById(promptText); const statusEl document.getElementById(status); let isDrawing false; let ctx scratchCanvas.getContext(2d); let resultCtx resultCanvas.getContext(2d); // 初始化用灰色填充刮刮乐涂层 function initScratchLayer() { ctx.fillStyle #cccccc; ctx.fillRect(0, 0, scratchCanvas.width, scratchCanvas.height); ctx.globalCompositeOperation destination-out; // 关键设置刮擦模式 } // 从后端AI获取图片 async function generateNewImage() { statusEl.textContent AI正在创作中...; generateBtn.disabled true; // 构建一个随机或固定的“好消息”提示词池 const promptPool [ 一只戴着礼帽的卡通猫举着‘恭喜发财’的横幅金色背景喜庆高清细节, 浩瀚宇宙中一个发光的宝箱打开光芒四射3D渲染梦幻, 一杯热气腾腾的咖啡旁边放着一张写有‘放松一下’的卡片温馨室内场景, 一个巨大的问号变成感叹号简约矢量风格蓝色背景, 赛博朋克城市中一条信息流显示‘任务完成’霓虹灯光 ]; const randomPrompt promptPool[Math.floor(Math.random() * promptPool.length)]; promptText.textContent randomPrompt; const payload { prompt: randomPrompt, negative_prompt: 低质量模糊变形文字水印, steps: 20, width: 512, height: 512, cfg_scale: 7, sampler_name: Euler a, }; try { const response await fetch(TXT2IMG_API, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify(payload) }); const data await response.json(); // 将Base64图片显示在底层画布 const img new Image(); img.onload function() { resultCtx.clearRect(0, 0, resultCanvas.width, resultCanvas.height); resultCtx.drawImage(img, 0, 0); statusEl.textContent 生成成功请刮开涂层。; initScratchLayer(); // 重新覆盖涂层 }; img.src data:image/png;base64,${data.images[0]}; } catch (error) { console.error(生成失败:, error); statusEl.textContent 生成失败请检查后端服务。; } finally { generateBtn.disabled false; } } // 刮擦交互事件监听 scratchCanvas.addEventListener(mousedown, () { isDrawing true; }); scratchCanvas.addEventListener(mouseup, () { isDrawing false; }); scratchCanvas.addEventListener(mousemove, draw); scratchCanvas.addEventListener(touchstart, (e) { e.preventDefault(); isDrawing true; }); scratchCanvas.addEventListener(touchend, () { isDrawing false; }); scratchCanvas.addEventListener(touchmove, draw); function draw(e) { if (!isDrawing) return; e.preventDefault(); const rect scratchCanvas.getBoundingClientRect(); let x, y; if (e.type.includes(touch)) { x e.touches[0].clientX - rect.left; y e.touches[0].clientY - rect.top; } else { x e.clientX - rect.left; y e.clientY - rect.top; } // 绘制圆形路径来“刮”掉涂层 ctx.beginPath(); ctx.arc(x, y, 20, 0, Math.PI * 2); // 刮擦半径20像素 ctx.fill(); } // 按钮事件 generateBtn.addEventListener(click, generateNewImage); resetBtn.addEventListener(click, initScratchLayer); // 页面加载初始化 window.onload function() { initScratchLayer(); generateNewImage(); // 页面加载后自动生成第一张 };启动前端服务 在项目目录下使用任意静态服务器启动。# 使用Python快速启动 python -m http.server 8080然后在浏览器中访问http://127.0.0.1:8080。4.3 步骤三联调与跨域处理由于前端页面运行在http://localhost:8080而后端API在http://127.0.0.1:7860浏览器会因同源策略阻止请求。解决方案A配置WebUI CORS推荐在启动WebUI的命令行参数中添加允许前端源# 修改 webui-user.bat 中的参数 set COMMANDLINE_ARGS--api --listen --cors-allow-origins http://localhost:8080解决方案B使用简易代理服务器在前端项目目录下创建server.jsconst express require(express); const { createProxyMiddleware } require(http-proxy-middleware); const app express(); // 静态文件服务 app.use(express.static(.)); // 代理AI后端API请求 app.use(/sdapi, createProxyMiddleware({ target: http://127.0.0.1:7860, changeOrigin: true, pathRewrite: { ^/sdapi: /sdapi, // 保持路径不变 }, })); app.listen(8080, () { console.log(前端代理服务器运行在 http://localhost:8080); console.log(API请求将被代理到 http://127.0.0.1:7860); });运行node server.js并访问http://localhost:8080。5. 功能测试与效果验证部署完成后通过以下步骤验证整个流程是否跑通。5.1 测试一后端AI服务连通性目标确认Stable Diffusion WebUI的API服务正常工作。操作在浏览器中直接访问http://127.0.0.1:7860/sdapi/v1/txt2img。如果返回的是405 Method Not Allowed因为这是POST接口这是正常的。访问http://127.0.0.1:7860/docs能看到API文档页面则说明服务已启动。使用curl测试curl -X POST http://127.0.0.1:7860/sdapi/v1/txt2img \ -H Content-Type: application/json \ -d {prompt:a cute cat, steps:5, width:64, height:64} \ --output test.png如果生成了一个很小的test.png图片说明API功能正常。5.2 测试二前端页面基础交互目标确认前端页面加载正常Canvas绘制和基础事件有效。操作访问http://localhost:8080。页面应显示“正在生成...”状态稍后出现被灰色涂层覆盖的区域。点击“重置刮卡”按钮涂层应恢复为完整的灰色。在灰色区域按下鼠标并拖动应能“刮”出透明区域露出底层画布颜色此时还没有AI图片。成功标准Canvas涂层能正确初始化鼠标/触摸交互能改变Canvas像素。5.3 测试三完整流程集成测试目标验证从前端点击按钮到AI生成图片并显示的全链路。操作确保后端服务运行且跨域已解决。刷新前端页面。观察状态提示应从“AI正在创作中...”变为“生成成功请刮开涂层。”。此时刮开涂层应能逐步看到一张由AI生成的、符合提示词描述的图片。点击“生成新好消息”按钮应能触发新一轮生成并更新图片和涂层。成功标准涂层下成功显示AI生成的图片且每次生成的图片内容不同。常见失败原因跨域错误浏览器控制台出现CORS错误。按4.3节解决。API请求失败控制台显示404或500错误。检查后端服务地址、端口是否正确WebUI是否以--api模式启动。图片显示为空白检查前端JS中解析Base64图片数据的代码是否正确data.images[0]路径是否匹配API返回结构。6. 接口API与批量任务本项目核心依赖后端AI服务的文生图API。理解这个API有助于你进行功能扩展。6.1 核心API调用详解Stable Diffusion WebUI的/sdapi/v1/txt2img接口是关键。请求示例 (Python)import requests import json import base64 from PIL import Image from io import BytesIO api_url http://127.0.0.1:7860/sdapi/v1/txt2img payload { prompt: 一只可爱的柴犬在草地上打滚阳光明媚摄影风格, negative_prompt: 低质量模糊丑陋, steps: 20, width: 512, height: 512, cfg_scale: 7, sampler_name: DPM 2M Karras, seed: -1, # -1表示随机种子 batch_size: 1 } response requests.post(api_url, jsonpayload) if response.status_code 200: r response.json() # 返回的图片是Base64编码字符串列表 image_base64 r[images][0] # 解码并保存图片 image_data base64.b64decode(image_base64) image Image.open(BytesIO(image_data)) image.save(generated_good_news.png) print(图片生成并保存成功) else: print(f请求失败: {response.status_code}) print(response.text)6.2 实现批量任务虽然前端交互是单次的但后端可以轻松支持批量生成用于准备素材库或测试。批量生成脚本示例import requests import json import base64 import time from pathlib import Path api_url http://127.0.0.1:7860/sdapi/v1/txt2img output_dir Path(./batch_outputs) output_dir.mkdir(exist_okTrue) prompt_list [ 金色的奖杯聚光灯下背景模糊3D渲染, 一扇打开的门门外是美丽的彩虹简约插画风格, 一个进度条显示100%完成科技感蓝色主题, 一堆彩色气球飞向蓝天卡通风格欢乐, 一个灯泡亮起里面有一个感叹号创意图标设计 ] for i, prompt in enumerate(prompt_list): print(f正在生成第{i1}张: {prompt[:30]}...) payload { prompt: prompt, steps: 15, # 批量生成可适当减少步数以加快速度 width: 512, height: 512, cfg_scale: 7, sampler_name: Euler a, seed: -1, } try: response requests.post(api_url, jsonpayload, timeout120) if response.status_code 200: r response.json() image_data base64.b64decode(r[images][0]) with open(output_dir / fgood_news_{i:03d}.png, wb) as f: f.write(image_data) print(f 已保存到 good_news_{i:03d}.png) else: print(f 生成失败状态码: {response.status_code}) except Exception as e: print(f 请求异常: {e}) # 避免请求过于频繁可适当间隔 time.sleep(2) print(批量生成任务完成)7. 资源占用与性能观察项目的性能瓶颈几乎完全集中在AI绘画后端。显存占用观察启动Stable Diffusion WebUI后使用nvidia-smiWindows/Linux或任务管理器Windows性能标签页查看GPU显存占用。加载一个基础的SD 1.5模型显存占用通常在3-4GB。加载SDXL模型可能超过8GB。生成图片时显存占用会有一个峰值取决于分辨率、批大小和模型复杂度。512x512分辨率单图生成峰值可能比基础占用高1-2GB。优化建议如果显存不足可以尝试使用--medvram或--lowvram参数启动WebUI或者使用显存优化版本如SD-Forge。生成速度在RTX 3060 (12GB)上20步生成一张512x512的图片大约需要2-5秒。速度受采样器Sampler、步数Steps、分辨率、显卡算力影响显著。前端交互刮卡本身对性能无要求纯Canvas 2D操作非常流畅。前端性能Canvas的globalCompositeOperation destination-out是性能关键它直接使用像素操作实现刮擦效果在现代浏览器中硬件加速良好。如果刮擦区域很大或非常频繁可以优化绘制半径和频率避免每帧绘制过大区域。8. 常见问题与排查方法问题现象可能原因排查方式解决方案前端页面打开空白或JS错误1. 静态服务器未启动。2. 文件路径错误。3. 浏览器缓存。1. 检查终端是否运行了python -m http.server等命令。2. 按F12打开开发者工具查看Console和Network标签页。1. 确保在项目目录下启动服务器。2. 使用无痕模式打开页面。3. 检查index.html中引用的script.js路径是否正确。点击“生成”按钮无反应控制台报CORS错误跨域请求被浏览器阻止。查看Console错误信息是否包含Access-Control-Allow-Origin。按4.3节配置后端CORS或使用代理服务器。生成图片时前端一直显示“AI正在创作中...”1. 后端API服务未运行或地址错误。2. 网络请求失败。3. AI生成过程出错或超时。1. 检查WebUI命令行窗口是否正常运行。2. 在浏览器中直接访问http://后端IP:端口/docs看是否可达。3. 查看WebUI后台日志是否有生成错误。1. 确认后端服务IP和端口并更新前端JS中的API_BASE_URL。2. 检查防火墙设置。3. 尝试用curl直接测试API缩小问题范围。刮擦无效果刮不开涂层1. Canvas绘图上下文ctx未正确设置合成模式。2. 事件监听未绑定。3. 涂层画布scratchCanvas被结果画布resultCanvas遮挡。1. 在initScratchLayer函数中打印ctx.globalCompositeOperation的值。2. 检查鼠标事件监听器是否成功添加。3. 使用浏览器开发者工具的Elements面板检查两个Canvas的z-index和位置。1. 确保在初始化涂层后执行ctx.globalCompositeOperation destination-out。2. 确认scratchCanvas的CSS样式position: absolute且位于resultCanvas之上。生成的图片质量差或不符合预期1. 提示词Prompt不够具体。2. 模型不适合该风格。3. 生成参数步数、CFG scale设置不当。1. 在后端WebUI界面用相同参数测试看是否是前端问题。2. 尝试更详细、更积极的提示词添加质量标签如masterpiece, best quality。3. 调整steps20-30、cfg_scale7-11。1. 优化提示词工程。2. 更换更适合的模型例如想生成动漫风格就下载动漫风格的Checkpoint。3. 在后端WebUI界面调试好参数再同步到前端代码。页面在移动端触摸不灵敏触摸事件处理不完善或触摸点坐标计算有误。在移动端打开开发者工具模拟触摸事件或使用真机调试。确保touchmove事件调用了e.preventDefault()防止页面滚动并正确计算相对于Canvas的坐标(e.touches[0].clientX - rect.left)。9. 最佳实践与使用建议项目结构分离将前端项目与后端AI服务完全分离。前端可部署到GitHub Pages、Vercel等静态托管平台后端API则可部署在本地、有GPU的云服务器或使用Serverless函数调用商用API。这样更清晰也便于独立更新。API密钥与安全如果使用在线AI服务如Replicate切勿将API密钥硬编码在前端JS中这会导致密钥泄露。务必通过自己的后端服务器进行中转或在Serverless函数中处理。用户体验优化加载状态像示例代码一样在AI生成时禁用按钮并显示加载状态避免用户重复点击。刮擦手感可以调整刮擦半径示例中是20像素和刮擦形状圆形、方形、图片纹理让手感更真实。生成失败友好提示捕获网络和API错误给用户明确的提示如“服务繁忙请稍后再试”。内容池与随机性建立一个丰富的“好消息”提示词池并加入随机种子确保每次刮开的惊喜感。可以结合节日、热点事件动态更新词库。性能与成本本地部署注意显存和电费成本。长时间运行可考虑设置自动休眠。云端API注意调用次数和费用为API设置用量限制和告警。合规与创意延伸确保生成的图片内容符合法律法规和公序良俗可在后端对提示词进行安全过滤。此框架可无限延伸将“刮刮乐”变成“擦雾玻璃”、“撕开信封”、“揭开幕布”交互逻辑类似只需修改前端Canvas的涂层视觉效果和交互反馈音效。10. 总结与下一步这个“AI刮刮乐”项目是一个绝佳的练手项目它巧妙地将生成式AI的“创造力”与前端的“交互性”结合在一起最终呈现出一个完整、有趣且具有传播力的应用。最值得尝试的点在于其清晰的分层架构后端专注生产内容AI生图前端专注消费和展示内容交互刮卡。你完全可以替换其中任何一层比如后端换成Midjourney API、DALL-E 3 API或者前端改用Three.js做成3D刮卡创造出属于自己的变体。最先应该验证的功能是后端API的连通性。只要curl或Python脚本能成功调通文生图接口项目就成功了80%。剩下的前端交互是相对标准的Web开发工作。最容易踩的坑就是跨域CORS问题和Canvas的图层叠加顺序。严格按照本文的步骤配置代理或CORS并仔细检查两个Canvas的CSS定位通常刮擦层需要position: absolute覆盖在结果层之上就能顺利解决。后续扩展方向有很多多模型支持让用户选择不同风格写实、动漫、水墨的模型来生成“好消息”。自定义提示词提供一个输入框让用户输入自己想要的好消息关键词。结果分享增加截图或保存功能让用户可以将刮开后的最终图片分享到社交媒体。移动端适配优化触摸体验将其封装成轻量级H5活动页。接入实际业务比如将“好消息”替换为“优惠券”、“抽奖结果”等用于电商或社区互动。建议将本项目代码作为基础模板收藏下次当你需要快速验证一个“AI交互”的想法时它可以为你节省大量搭建环境的时间。