通义万相 + OSS:给商会活动做一套自动生成海报的方案

简介: 商会年办十余场活动,海报设计成本高、效率低。我们采用“AI生成底图+前端Canvas合成文字”方案:用通义万相turbo版快速产出无文字背景图,再由前端精准叠加标题、时间等关键信息并上传OSS。兼顾准确性、统一性与低成本,全年节省设计费用数万元。(239字)

商会办活动的频率不低,一年十几场。每场活动都要出海报——年会、对接会、走访、沙龙,样式还要有形有色。秘书长找设计做,一张海报几十到几百块,一年下来也是一笔开销;找会员里的设计师帮忙,欠人情。

去年我们把这件事自动化了。这篇把方案记下来:用通义万相生成底图,前端合成文字,上传到 OSS,全程不用人画图。

先说清楚边界

有一点要先说明:我们没有让模型直接生成带文字的完整海报。原因很实际——文生图模型写汉字的能力不稳定,生成的标题经常是错字或者乱码。商会的海报上,活动名称、时间、地点必须准确,错一个字就不敢往外发。

所以方案拆成两步:模型只负责生成底图(背景、氛围、配色),文字部分用前端 Canvas 合成。这样既省了设计成本,文字又完全可控。

整体架构

流程是四步。第一步,活动信息录入系统,拿到标题、时间、地点、主办方。第二步,把活动类型映射成提示词模板,调通义万相生成底图。第三步,前端用 Canvas 把底图和文字合成一张完整海报。第四步,合成结果上传 OSS,拿到链接返回给前端。

为什么要拆成"模型出底图、前端合文字"两步,而不是让模型一步出完?除了前面说的汉字准确性问题,还有一个考虑是可复用性。同一张底图,换个活动标题就能再用一次;如果让模型把文字也画进去,每换一个活动就要重新生成一次,成本和耗时都上去了。

还有一点是版式对齐。商会的海报经常要发给会员、发到群里,版式得统一。让模型自由发挥,每一张的标题位置、字号都不一样,看起来不像一个系列。用 Canvas 合成,版式是写死在代码里的,几十张海报的标题都在同一个位置。

调用通义万相

用 DashScope 的 Node SDK。文生图是异步接口,提交任务之后拿 task_id 去轮询结果。

import DashScope from 'dashscope-sdk';

const client = new DashScope({
    apiKey: process.env.DASHSCOPE_KEY });

async function generatePoster(prompt) {
   
  // 1. 提交任务
  const task = await client.images.generations.create({
   
    model: 'wanx2.1-t2i-turbo',
    input: {
    prompt },
    parameters: {
    size: '1024*1536', n: 1 }
  });
  const taskId = task.output.task_id;

  // 2. 轮询结果,超时上限设为 60 秒
  const deadline = Date.now() + 60_000;
  while (Date.now() < deadline) {
   
    const res = await client.tasks.get(taskId);
    const status = res.output.task_status;
    if (status === 'SUCCEEDED') {
   
      return res.output.results[0].url; // 底图临时地址
    }
    if (status === 'FAILED') {
   
      throw new Error('底图生成失败: ' + res.output.message);
    }
    await new Promise((r) => setTimeout(r, 2000));
  }
  throw new Error('底图生成超时');
}

模型选型上我们对比过。通义万相的 turbo 版本生成速度快,两三秒出图,适合这种批量、对细节要求不高的场景;标准版出图质量更细腻,但耗时长,用在需要精修的场合。商会的活动海报对画质要求不高——发出去看的是信息,不是画质细节——所以选了 turbo 版本。

提示词模板按活动类型分开维护。年会用偏正式的红金配色,对接会用偏商务的蓝白配色,沙龙用轻松一点的浅色系。

const PROMPT_TPL = {
   
  annual: '年会庆典海报背景,红色与金色为主,喜庆庄重,留白区域在下方三分之一,无文字',
  match: '商务对接会海报背景,蓝色与白色为主,简洁现代,留白区域在下方三分之一,无文字',
  salon: '轻松沙龙海报背景,浅米色与绿色为主,柔和自然,留白区域在下方三分之一,无文字'
};

function buildPrompt(type) {
   
  return PROMPT_TPL[type] || PROMPT_TPL.salon;
}

提示词里"无文字"这三个字很关键,不加的话模型会自己往上写一堆看不懂的字符,后期不好处理。

前端 Canvas 合成文字

底图拿到之后,前端把底图画到 Canvas 上,再往上写文字。

async function compose(bgUrl, info) {
   
  const img = new Image();
  img.crossOrigin = 'anonymous';
  await new Promise((res, rej) => {
   
    img.onload = res;
    img.onerror = rej;
    img.src = bgUrl;
  });

  const canvas = document.createElement('canvas');
  canvas.width = img.width;
  canvas.height = img.height;
  const ctx = canvas.getContext('2d');
  ctx.drawImage(img, 0, 0);

  // 底部加一层半透明遮罩,保证文字可读
  ctx.fillStyle = 'rgba(0,0,0,0.35)';
  ctx.fillRect(0, img.height * 0.62, img.width, img.height * 0.38);

  ctx.textAlign = 'center';
  ctx.fillStyle = '#ffffff';

  ctx.font = `bold ${
     img.width * 0.075}px "PingFang SC", "Microsoft YaHei", sans-serif`;
  ctx.fillText(info.title, img.width / 2, img.height * 0.72);

  ctx.font = `${
     img.width * 0.04}px "PingFang SC", "Microsoft YaHei", sans-serif`;
  ctx.fillText(`时间:${
     info.time}`, img.width / 2, img.height * 0.8);
  ctx.fillText(`地点:${
     info.place}`, img.width / 2, img.height * 0.85);
  ctx.fillText(info.org, img.width / 2, img.height * 0.92);

  return canvas;
}

上传 OSS

合成完拿到 canvas,转成 blob 上传。上传走服务端签名,直传 OSS,不经过应用服务器。

async function uploadPoster(canvas, fileName) {
   
  // 1. 向服务端要直传签名
  const {
    policy, signature, ossAccessKeyId, host, dir } =
    await fetch('/api/oss/sign').then((r) => r.json());

  const blob = await new Promise((res) =>
    canvas.toBlob(res, 'image/png', 0.92)
  );

  const form = new FormData();
  form.append('key', dir + fileName);
  form.append('policy', policy);
  form.append('OSSAccessKeyId', ossAccessKeyId);
  form.append('signature', signature);
  form.append('success_action_status', '200');
  form.append('file', blob);

  await fetch(host, {
    method: 'POST', body: form });
  return `${
     host}/${
     dir}${
     fileName}`;
}

服务端签名用 STS 临时凭证,不要用主账号 AK,权限只给到指定目录的写权限。

这套方案跑了一年,跟两种替代方式对比过。一种是纯人工找设计做,一张海报几十到几百块,一年十几场活动攒下来不是小数,而且设计的档期经常赶不上活动临时改时间。另一种是第三方海报 SaaS,模板多但风格偏通用,商会的红金喜庆调性得反复调,而且数据在别人服务器上。自己搭这套方案,前期多花点开发时间,后面每次活动点一下就出图,长期看划算。

踩过的坑

第一个是跨域。Canvas 要读底图的像素,底图跨域的话 canvas 会被污染,toBlob 会报错。解决办法是给 OSS 的 Bucket 配跨域规则,并且 img 标签设 crossOrigin。

第二个是异步轮询。文生图是异步的,提交完不能直接拿结果。一开始没做超时,遇到一次任务卡住,前端一直转圈。加上超时和失败处理之后正常了。

第三个是字体。Canvas 里用的字体必须是用户机器上有的,不然会退化成默认字体,海报排版会散。中文字体统一用系统字体族兜底。

第四个是底图的有效期。通义万相返回的底图地址是临时的,合成上传要在这个地址失效前完成。做法是拿到底图后立刻合成上传,不做缓存。

第五个是生成结果不合用。模型出图有随机性,同一句提示词也可能出一张风格跑偏的图。我们的做法是一次生成两张,前端做成左右选择,秘书长挑一张继续合成。多一次请求的成本,比让秘书长重走一遍流程低。

我们这边在跑的商会管理系统叫未来漫城·商会互联平台,上面这套海报生成现在嵌在活动发布流程里,秘书长填完活动信息点一下,两三分钟出一张海报。

相关文章
|
20天前
|
人工智能 缓存 前端开发
DeepSeek Harness 首发实测 + 入门教程,夯爆了!梁神我错了
DeepSeek Harness + DeepSeek V4 Pro 项目实战保姆级教程!手把手带你从零安装开源 AI 编程工具,开发架构图、知识讲解网站、3D 网页游戏、全栈 AI 应用 4 个项目,覆盖运行模式选择、插件安装与开发,看看能不能对标 Claude。
13288 91
DeepSeek Harness 首发实测 + 入门教程,夯爆了!梁神我错了
|
9天前
|
人工智能 自然语言处理 安全
阿里云千问办公、Qoder Teams、Qoder CN区别与选择指南:模型能力、适用场景与最新活动参考
本文聚焦阿里云2026年推出的三款自研AI办公产品,清晰拆解千问办公、Qoder Teams、Qoder CN的差异化定位与能力边界:千问办公主打职场全场景提效,支持自然语言指令一键完成PPT生成、数据分析等高频办公任务;Qoder Teams面向程序员团队,深度整合AI代码生成、团队协同与企业知识库能力;Qoder CN则专为金融、政务等强合规场景打造,实现数据不出境与VPC私有化部署。文章同步给出分场景选型指南与最新活动定价,帮助不同类型的企业按需组合产品,实现业务岗、研发岗与强合规场景的AI能力全覆盖。
阿里云千问办公、Qoder Teams、Qoder CN区别与选择指南:模型能力、适用场景与最新活动参考
|
14天前
|
Web App开发 人工智能 API
16 个超火的 DeepSeek Harness 插件,大肥鱼已经落后 N 个版本了。。。
DeepSeek Harness 精选插件推荐合集,从图片识别、浏览器操控、多 Agent 协作到手机远程控制,一口气带你看完 DSH 社区热门的十几个插件,覆盖技能扩展、UI 界面增强、整活玩法三大类,让你的鲸鱼变得更强。
1812 4
|
15天前
|
人工智能 Java BI
【AI】DeepSeek Harness 安装、运行、管理插件
本文介绍了如何运行DeepSeek开源的Agent框架DeepSeek Harness(dsh)。主要内容包括:使用nvm安装适配的Node版本;通过代理加速克隆GitHub源码;使用pnpm安装依赖并启动项目;配置DeepSeek API Token;安装扩展功能的插件。该框架自带Web界面,支持模型适配、文件编辑等插件化功能
2009 1
|
人工智能 JavaScript 开发工具
DeepSeek Harness 本地安装与使用指南
DeepSeek Harness(DSH)是DeepSeek AI开源的Agent运行框架,支持本地文件操作、命令执行与工具调用。基于Cordis插件架构,具备高扩展性与强可控性,适合开发者搭建可控Agent环境或开展模型基准测试。当前为开发者预览版,需Node.js环境,推荐先用`npx @deepseek-ai/dsh web`快速体验。
5281 0
|
9天前
|
人工智能 Linux iOS开发
Ollama使用教程:Ollama官网下载、Ollama本地部署大模型(2026最新)
Ollama 是一款免费开源的本地大模型运行工具,支持在 Windows/macOS/Linux 上离线运行 Qwen、DeepSeek、Llama 等主流开源模型,数据不出本机、隐私安全。提供 OpenAI 兼容 API,命令行一键拉取/运行/管理模型,无需联网,无调用限制,是开发者与 AI 爱好者部署本地 AI 助手的理想选择。(239 字)
|
17天前
|
人工智能 JavaScript 测试技术
保姆级教程:DeepSeek Harness从安装到跑通测试,30分钟上手
DeepSeek Harness是DeepSeek开源的AI Agent运行时,主打“一行命令安装、5分钟跑通”。它让模型真正动手干活——读代码、跑测试、分析失败、生成修复方案。本文手把手教你30分钟从零上手,覆盖安装、配置、实测及避坑指南,助你快速掌握下一代AI编程范式。
|
6天前
|
人工智能 监控 测试技术
Qwen3.8-Flash 来了,100万上下文、Agent、Coding 都加强了
8月26日,通义千问发布Qwen3.8-Flash-Next:125B参数、每Token仅激活6B,原生支持26万Token、可扩展至100万上下文;Coding、Agent与工具调用能力显著增强,面向真实软件工程任务,推动大模型从“回答问题”迈向“完成工作”。