资讯动态

Electron 桌面应用接入通义万相:文生图从 0 到 1 实战

发布时间:2026/9/12 2:11:25 来源:尧图企业网站定制
Electron 桌面应用接入通义万相文生图从 0 到 1 实战 想在 Electron 应用里一键「画」出小说封面、海报、插画阿里云通义万相文生图是个不错的选择。本文以 51mazi 小说写作软件的 AI 封面功能为例手把手讲清主进程如何安全调用 API、图片如何落盘到书籍目录、以及渲染进程如何优雅对接。看完你就能在自己的 Electron 项目里接好通义万相实现「提示词 → 图片 → 本地文件」全链路。 目录 Electron 桌面应用接入通义万相文生图从 0 到 1 实战 目录 为什么选通义万相️ 整体架构主进程干活渲染进程展示 核心实现服务层 IPC 落盘1. 服务层通义万相文生图2. IPC生成封面 确认使用 丢弃3. Preload统一暴露避免「is not a function」️ 安全与体验Key 存储、错误码、提示语 完整代码在哪看 小结与 GitHub️ 标签 为什么选通义万相通义万相是阿里云百炼平台提供的文生图能力适合在桌面应用里做「根据文字生成图片」的功能✅国内服务延迟低、无需科学上网✅REST APIPOST JSON和 Electron 主进程里的fetch天然契合✅模型能力支持中文提示词、多种尺寸、正向/反向提示词适合小说封面、插画等场景✅按量计费个人或小团队可控成本在 51mazi 里我们用它做「AI 生成小说封面」用户输入书名、笔名、风格描述由通义万相生成图片再保存到书籍根目录如ai_cover1.png、确认后复制为cover.png。️ 整体架构主进程干活渲染进程展示原则和接入 DeepSeek 时一致API Key 和网络请求只在主进程渲染进程只发 IPC、不碰 Key。┌─────────────────────┐ │ Vue 组件 │ 渲染进程填写提示词、选尺寸、点「生成」 │ (AICoverDrawer) │ └──────────┬──────────┘ │ IPC: tongyiwanxiang:generate-cover ▼ ┌─────────────────────┐ │ Preload │ contextBridge 暴露 generateAICover、confirmAICover 等 └──────────┬──────────┘ │ ▼ ┌─────────────────────┐ │ 主进程 │ 调用 tongyiwanxiang 服务 → 拿到图片 URL → 下载 → 写入书籍目录 │ tongyiwanxiang.js │ └──────────┬──────────┘ │ HTTPS ▼ ┌─────────────────────┐ │ 阿里云 通义万相 API │ dashscope.aliyuncs.com └─────────────────────┘这样做的直接好处安全API Key 存在 electron-store用户目录渲染进程拿不到。可控限流、重试、错误码解析都可以在主进程统一处理。可维护换模型或换接口时只改主进程服务层即可。 核心实现服务层 IPC 落盘1. 服务层通义万相文生图在主进程里单独建一个服务类如src/main/services/tongyiwanxiang.js只做三件事组请求体 → 发 HTTP → 解析返回里的图片 URL。接口形式以当前使用的多模态生成接口为例URLhttps://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation鉴权HeaderAuthorization: Bearer API KeyBodymodel、input.messages[].content[].text提示词、parameters尺寸、负向提示词、是否扩展提示词等核心代码示例// src/main/services/tongyiwanxiang.jsconstDASHSCOPE_API_BASEhttps://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generationconstMODELwan2.6-t2iclassTongyiwanxiangService{asyncgenerateCover(options{}){const{prompt,size1280*1280,negativePrompt}optionsconstbody{model:MODEL,input:{messages:[{role:user,content:[{text:prompt.trim()}]}]},parameters:{prompt_extend:true,watermark:false,n:1,negative_prompt:negativePrompt||,size:String(size)}}constresponseawaitfetch(DASHSCOPE_API_BASE,{method:POST,headers:{Content-Type:application/json,Authorization:Bearer${this.apiKey}},body:JSON.stringify(body)})constdataawaitresponse.json().catch(()({}))if(data.code){thrownewError(this._formatErrorMessage(data.code,data.message))}constimageUrldata.output?.choices?.[0]?.message?.content?.[0]?.imageif(!imageUrl)thrownewError(接口未返回有效图片地址)returnimageUrl}}返回的imageUrl是临时可访问的地址需在有效期内通常 24 小时内下载到本地否则会失效。所以下一步就是在主进程里「下载 → 落盘」。2. IPC生成封面 确认使用 丢弃主进程注册三个 IPC Handler对应前端三个操作操作IPC Channel作用生成封面tongyiwanxiang:generate-cover调服务 → 拿 URL → 下载 → 保存到书籍目录ai_cover1.png、ai_cover2.png…确认使用tongyiwanxiang:confirm-cover把用户选中的那张复制为cover.png取消/关闭tongyiwanxiang:discard-ai-covers当前实现不删文件仅关闭弹框生成封面的主流程示例逻辑在主进程// 1. 调通义万相拿到图片 URLconstimageUrlawaittongyiwanxiangService.generateCover({prompt,size,negativePrompt})// 2. 下载图片constresawaitfetch(imageUrl)constbufBuffer.from(awaitres.arrayBuffer())// 3. 保存到书籍根目录ai_cover1.png, ai_cover2.png ...constexistingfs.readdirSync(bookPath).filter((f)/^ai_cover\d\.png$/i.test(f))constnextNumexisting.length0?1:Math.max(...existing.map(解析数字))1constfileNameai_cover${nextNum}.pngconstcoverPathjoin(bookPath,fileName)fs.writeFileSync(coverPath,buf)return{success:true,localPath:coverPath}这样渲染进程拿到的就是本地路径可以直接用file://做预览确认使用时再根据chosenPath复制为cover.png即可。3. Preload统一暴露避免「is not a function」渲染进程通过window.electron.generateAICover、confirmAICover等调用。若只在contextIsolated true时通过contextBridge暴露了这些方法而在contextIsolated false时只挂了electronAPI就会出现「confirmAICover is not a function」。做法把「自定义 API」抽成一份如customElectronAPI两种情况下都挂到window.electron上constcustomElectronAPI{// ... 其他 APIgenerateAICover:(options)ipcRenderer.invoke(tongyiwanxiang:generate-cover,options),confirmAICover:(options)ipcRenderer.invoke(tongyiwanxiang:confirm-cover,options),discardAICovers:(options)ipcRenderer.invoke(tongyiwanxiang:discard-ai-covers,options)}if(process.contextIsolated){contextBridge.exposeInMainWorld(electron,{...electronAPI,...customElectronAPI})}else{window.electron{...electronAPI,...customElectronAPI}}这样无论是否开启上下文隔离前端都能稳定调到这些方法。️ 安全与体验Key 存储、错误码、提示语API Key从 electron-store 读如tongyiwanxiang.apiKey只在主进程使用不通过 IPC 把 Key 本身传给渲染进程。错误码通义万相会返回code如InvalidApiKey、DataInspectionFailed、Throttling在主进程里用_formatErrorMessage转成中文提示再通过 IPC 返回给前端展示。体验生成时前端可提示「正在努力生图中不要关闭弹框」并禁用关闭或二次点击避免中途关掉导致状态错乱。 完整代码在哪看实现涉及的文件src/main/services/tongyiwanxiang.js通义万相服务层src/main/index.jstongyiwanxiang:generate-cover/confirm-cover/discard-ai-covers的 IPC 实现src/preload/index.jscustomElectronAPI与window.electron的挂载src/renderer/src/service/tongyiwanxiang.js前端对generateAICover、confirmAICover的封装src/renderer/src/components/AICoverDrawer.vue封面生成弹框 UI 与提示词拼接书名、笔名、风格可直接在仓库里按文件名搜索每个模块都有注释便于对照本文捋清链路。 小结与 GitHub在 Electron 里接入通义万相文生图核心就是三件事主进程服务层组好请求、调 API、拿图片 URL并做好错误码与异常处理。主进程 IPC 落盘下载图片、按规则命名如ai_cover1.png、确认后复制为cover.png所有写盘都在主进程完成。Preload 统一暴露自定义 API 与 electronAPI 合并后一起挂到window.electron避免上下文隔离开关导致的方法缺失。按这个思路你可以把「通义万相 Electron」复用到任何需要文生图的桌面功能上海报、插画、配图等。若你想直接看完整工程和交互细节欢迎到 51mazi 仓库里翻代码、提 Issue 或 Star。GitHub 仓库https://github.com/xiaoshengxianjun/51mazi ⭐ 给个 Star 支持一下通义万相 API 文档阿里云百炼 - 文生图️ 标签#Electron#通义万相#文生图#阿里云#桌面应用#Vue3#IPC#51mazi如果这篇文章对你有帮助请在GitHub上给个 ⭐️ 支持一下本文基于 51mazi 开源项目通义万相文生图接入方案

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价