Cloudflare Images 图片添加文字实战:在 Worker 中生成成品卡片
用 Cloudflare Images 的 .text()、.draw() 和 .output() 在 Worker 内完成图片添加文字、图层合成与 WebP 输出。本文给出完整代码,并拆解字体与尺寸限制、Workers Cache、唯一转换计费,以及自动化社交卡片、商品促销图和状态图片的适用场景与风险边界。

在 Cloudflare Worker 内,把一张商品图和一段实时字符串直接合成为可发布的社交卡片。新的 .text() 文本源会生成栅格文字图层,.draw() 负责把它放到图片上,.output() 则返回最终文件。借助这条图片添加文字流程,固定版式的发布系统可以在同一条处理链中完成缩放、加标签、编码与交付,无须把任务转给浏览器渲染器或第二个图片 API。
Cloudflare Images 图片添加文字:最短可运行流程
先从一套可重复使用的版式开始。下面的示例会生成一张 1200 × 630 的商品卡片,从 ?text= 读取标题,使用固定的品牌字体,并返回 WebP。请把两个 example.com 资源 URL 换成自己可控的地址。
在 Wrangler 配置中添加 Images 绑定,并启用 Workers Cache:
{
"images": {
"binding": "IMAGES"
},
"cache": {
"enabled": true
}
}然后在 Worker 中调用该绑定:
const CARD_IMAGE = "https://assets.example.com/product-card.jpg";
const BRAND_FONT = "https://assets.example.com/fonts/Brand-Bold.woff2";
export default {
async fetch(request, env) {
const url = new URL(request.url);
const headline = (url.searchParams.get("text") || "AUTUMN DROP").trim();
// This is a layout limit for this card, not Cloudflare's 1,000-character ceiling.
if (!headline || [...headline].length > 120) {
return new Response("Text must contain 1 to 120 characters", { status: 400 });
}
const source = await fetch(CARD_IMAGE);
if (!source.ok || !source.body) {
return new Response("Source image unavailable", { status: 502 });
}
const textLayer = env.IMAGES.text(headline, {
font: { url: BRAND_FONT },
size: 72,
color: "#FFFFFF"
});
const result = await env.IMAGES
.input(source.body)
.transform({ width: 1200, height: 630, fit: "cover" })
.draw(textLayer, { left: 72, bottom: 72 })
.output({ format: "image/webp" });
return result.response({
headers: {
"Cache-Control": "public, max-age=86400, stale-while-revalidate=604800"
}
});
}
};请求 /card?text=Autumn%20Drop 后,输出是一张 1200 × 630 的 WebP,传入的文字距离左边缘和下边缘各 72 像素。图片 URL 中包含动态文字,因此这个示例会自然地为每条文案生成独立 URL。生产环境中应尽量使用稳定的活动 ID 或商品 ID。若把任意文本直接放进公开查询参数,可能产生无限多种图片变体,既增加成本,也带来滥用风险。
源图片和字体的来源必须固定,或纳入允许列表。示例不会让访问者自行指定任意抓取目标;只要公开 Worker 能读取远程资源,这条边界就很重要。
Cloudflare 在背后究竟做了什么
文字栅格化,就是把字符变成像素。可以把 .text() 看成一台小型排版机:它先印出一张透明文字贴纸,.draw() 再把贴纸铺到照片上,最后由 .output() 将两者封装成成品文件。
理解这个模型,API 的设计就很直观了。这里的文字不是悬浮在浏览器图片上方的 HTML 元素;渲染完成后,它已经成为图片像素的一部分。
基础图片决定最终画布尺寸。文字可通过 top、left、bottom 或 right 指定像素偏移;不设置位置时默认居中。同一个叠加层不能同时设置 left 与 right,也不能同时设置 top 与 bottom。不透明度范围为 0 到 1,默认合成模式是 over。
可以连续调用多次 .draw()。调用顺序就是图层顺序,因此最后绘制的内容位于最上方。Cloudflare 还为基于 URL 的转换在 cf.image.draw 数组中加入了 text 项;不过,如果基础图片本来就是从 R2、Cloudflare Images、请求体或另一项 fetch 获取的原始字节,使用绑定通常更合适。
真正缺少的是智能排版能力。Cloudflare 目前为文字样式明确记录的只有 font、size 和 color,并未提供文本框、自动换行、字号自适应、行高、字距、对齐、描边、阴影或字体回退等文档化能力。换行位置、安全区域,以及商品名过长时如何处理,都要由应用自行决定。
缓存成品卡片,而不只是源图
Images 绑定的响应不会自动缓存。如果不使用 Workers Cache,同一请求每次都会运行 Worker,并重新解码、编码源图片。启用缓存并设置 Cache-Control 后,Cloudflare 就能直接交付已完成的响应,不必重复这套处理。
缓存与 Images 计费解决的是两个不同问题。Cloudflare 按唯一转换组合对绑定计费:源图片与参数的每一种唯一组合,在每个日历月内只计 1 次;同月重复执行同一转换,不会增加 Images 用量。缓存命中依然有价值,因为它还能减少重复的 Worker 执行和图片处理延迟。
Cloudflare 并未单独说明在唯一性计算中会如何规范化文字字符串。因此,更稳妥的容量规划是假定每一种不同的基础图片、文案、样式和输出组合都是新的转换,直到自有用量数据证明并非如此。一个包含 2,000 款商品、5 种卡片尺寸的目录,可能就会形成 10,000 个变体,即使每张卡片都被查看了数千次也是如此。
版式已由团队掌控,成本账就会改写
Cloudflare Images Free 每月包含 5,000 次唯一转换。付费方案仍包含前 5,000 次,超出部分每 1,000 次收费 $0.50。按照 Cloudflare 自己的 10,000 次转换示例,当月 Images 转换费用为 $2.50。
Bannerbear 目前列出的 Automate 方案价格是每月 $49,包含 1,000 个 API credits;Scale 方案是每月 $149,包含 10,000 个 credits。普通图片每渲染 1 次会消耗 1 个 credit,额外格式、缩放或 AI 图层的倍数计费尚未计算在内。
$146.50 的差价并不等于开箱即用的节省。Bannerbear 出售的是一套可以直接工作的设计产品,包含模板编辑器、集成能力与团队工作流。Cloudflare 提供的是渲染原语,版式设计、编码、验证、监控和维护仍由使用方承担。除了 Images 转换费,还可能产生源文件存储与工程投入;存放在 Cloudflare Images 内的资源也有独立价格。
但决策边界依然很清晰。如果团队已经掌握设计规则,图片请求也运行在 Cloudflare 上,那么单独订阅渲染服务就可能不再必要。如果市场团队每周都要通过可视化界面移动图层,订阅费用买到的是编辑器和运营方式,而不是昂贵的像素。
最值得采用的 7 类工作流(按优先级排序)
1. 商品目录营销卡片
拥有数百个 SKU 的零售商可以保留一套审核通过的背景版式,再把实时商品名、价格、库存提示或促销信息绘制到每张卡片上。库存或活动数据触发 Worker,由它返回完成的商城或社交媒体素材。这样一来,价格变化不再带来人工导出队列,同一套已批准版式也能反复生成,而无须修改源照片。
它最适合长度有明确边界的文案。两行商品名加一个价格标签通常可以预测,一整段促销文案则不行。
2. 出版平台与 CMS 社交卡片
文章发布时,内容平台可以调用一个端点,传入标题或稳定的文章 ID。Worker 拉取头图、渲染标题,再返回 Open Graph 图片或社交卡片。它能减少缺失或过期的分享图片,也不用让发布流程等待截图浏览器。
当 CMS 已经运行在 Cloudflare 后方时,这种方案尤其合适。图片可以在负责交付它的同一边缘层生成,并把成品 URL 缓存起来,应对后续重复分享。
3. 交易平台状态图片
交易平台可以在商品卡片上标注 NEW、RESERVED、SOLD、成色或地点。商品服务只需修改一个很小的文本值,图片端点就能产出新的视觉状态。卖家无须编辑原始照片,买家也能在卡片出现的任何位置直接看到状态。
商业价值在于准确性。过期的状态卡片会增加客服工作,也会制造令人失望的点击;确定性的叠加层则可以随记录同步变化。
4. 连锁门店与本地优惠素材
餐饮或服务连锁可以保持品牌构图不变,只按地区替换城市、优惠、日期或价格。一套活动定义即可生成大量本地版本,在减少重复制作的同时,把字体、颜色和位置等高风险部分留在本地运营人员的权限之外。
超长地名是主要陷阱。要安全地自动化,工作流必须预先准备文字宽度测量、备用字号或审核通过的缩写。
5. 活动与日程卡片
活动平台可以把演讲者姓名、场次时间、房间号或临时出现的 CANCELLED 状态渲染到固定海报上。源日程仍是事实记录,卡片生成只是一个输出步骤。临近活动才发生信息变化时,无须让设计师重新打开几十个文件,速度优势尤其明显。
6. 客户报告快照
报告类产品可以在品牌化图表图片上添加周期、客户名称和核心指标,用于邮件或即时通信。Worker 以已经渲染好的图表为底图,只补上少量变化的标签,然后返回紧凑的最终格式。当接收端无法运行仪表盘本身时,这种做法很实用。
不要用文字图层绘制完整仪表盘。它最擅长的是最后一步、规则确定的加标签工作。
7. 内部运营标签
仓库、现场服务团队或内容审核队列可以把简短状态写到物品照片上,例如检查状态、批次、路线或审核结果。图片离开原系统、周边元数据被剥离后,这类视觉标签依然能随图传递,接收者也能少做几次查询。
这只是运营便利,不能替代底层记录。状态仍应保存在数据库中,图片只作为一种视图。
值得做的 3 个产品
最佳机会:垂直领域社交卡片端点
面向已有固定版式、但不想维护浏览器渲染技术栈的出版商、代理机构或多门店企业,打造一项品牌安全的卡片服务。客户提供头图和获批的文案字段,服务则为少量固定宽高比返回稳定 URL。
美国关键词数据估算,social media post maker 每月有 480 次搜索,单次点击成本为 $19.95。这个精确短语覆盖的人群比 API 买家更广,但异常高的 CPC 表明,供应商正在争夺这类生产任务。Bannerbear 每月 $49 和 $149 的两个价位,也为已经付费使用自动渲染的团队提供了当前预算参照。
最小可售版本包括 1 个 Worker、3 套锁定版式、管理端预览、CMS webhook、严格的来源允许列表、稳定的缓存键,以及专门处理文字溢出的失败队列。要出售的是发布连接的可靠性,而不是裸露的 .text() 调用。
难点在于模板归属。Cloudflare 不提供面向客户的可视化编辑器,每新增一种版式都可能变成服务工作。尽管如此,它仍是最强的机会:新的原语能从一个重复且具有商业价值的流程中移除渲染器,同时把集成和品牌治理留作产品价值。
商品目录促销标签引擎
为电商团队打造由商品数据源驱动的合成服务,把价格、促销状态、配送承诺或系列名称添加到商品图片上。CSV、PIM 或电商 webhook 更新数据后,服务只重新生成有变化的变体。
Product label maker 在美国每月约有 320 次搜索,具有商业意图,CPC 为 $6.03,广告主竞争度高。这说明标签制作确实存在付费需求,尽管搜索者中很大一部分要找的是可打印标签,而不是商品目录图片。
MVP 需要一个商品数据源连接器、少量固定徽标、宽高比预设、预览功能,以及处理超长名称和缺失价格的规则。难点是控制范围:实体包装还涉及印刷分辨率、出血、条码和监管审核,单靠这项栅格文字叠加能力无法解决。除非产品本身已经覆盖这些系统,否则应专注于促销图片标签。
可嵌入的图片加文字工具
为已有的创作、交易或社区产品开发一个小型编辑器组件:选择图片,输入短文字,从批准的字体和颜色中选择样式,在安全区域内调整位置,然后导出。Cloudflare 在产品自己的界面背后完成最终栅格化。
Add text to image 在美国每月约有 6,600 次搜索。交易意图更强的 add text to image app 约有 320 次搜索;在同一数据集中,它的同比增幅为 23%。需求确实存在,但很多搜索者期待的是免费、通用的编辑器。
MVP 是一个受约束的预览界面、4 到 6 种文字预设、1 个导出端点,以及成品 URL 存储。难点是护城河较弱:独立的通用工具要与成熟的免费编辑器竞争。更合理的定位,是把它做成某个现有产品中的付费功能;该产品已经掌握图片、用户和发布目的地。
哪些场景不该用它
Cloudflare Images 可以渲染文字并完成图层合成,但它不会决定文案内容、让排版自动响应、审批品牌版式,也不提供面向市场人员的模板编辑器。如果这些才是任务中最难的部分,那么维护一套完整设计自动化产品的成本可能仍低于自建。若要进一步了解整个品牌系统如何变化,可以参阅 Canva AI 2.0 品牌焕新测试。
遇到以下 5 种情况,应及时停下来:
- 文案需要复杂换行、字号自适应、富文本,或者所选字体的特定文字塑形效果尚未经过测试。
- 编辑人员需要在可视化界面中移动图层,并且不依赖开发者就能发布新模板。
- 公开端点会接受任意源图片或字体 URL,却没有允许列表。
- 无法限制变体数量,随机查询字符串可能耗尽 Free 方案的 5,000 次转换额度,并让新请求以错误 9422 失败。
- 本地测试依赖文字渲染。低保真的本地 Images 实现只支持宽度、高度、旋转和格式,因此这项功能要使用
npx wrangler dev --remote。
字体和文字限制是硬边界:自定义字体最大 20 MB,渲染内容最长 1,000 个字符,栅格图层最大 4096 × 4096 像素。这些上限对标签和标题已经很宽裕,但不能因此把图片 API 当作页面布局引擎。
怎样创建带文字叠加的图片?
先通过 env.IMAGES.input(imageBytes) 创建基础图片句柄,再用 env.IMAGES.text(content, { font, size, color }) 生成文字图层,把它传给 .draw(),最后调用 .output({ format })。输出尺寸由基础图片决定。
怎样在图片上添加叠加层?
使用 Images 绑定时,把图片句柄或 .text() 句柄作为叠加层传给 .draw(overlay, options)。通过 top、left、bottom 或 right 设置像素偏移;需要半透明效果时使用 opacity。继续串联 .draw() 即可增加图层,最后一次绘制的内容位于最上方。
图片文字叠加应该怎么做?
处理原始图片字节时,使用上文的 Images 绑定流程。若通过 URL 执行 fetch() 转换,就在 cf.image.draw 数组中加入 text 项,并提供同样的 font、size 和 color 选项。当源图片来自 R2、Cloudflare Images、请求体或另一个 fetch 响应时,绑定通常更简洁。
怎样把文字放到图片主体后面?
这项文字功能没有文档化的自动主体分离能力,也没有简单的 behind 开关。绘制顺序决定哪个叠加层位于上方,合成模式则决定像素如何结合。要把文字放到人物或商品后方,需要另行准备主体蒙版或前景图层,并在文字之后绘制。
怎样让照片中的文字动起来?
这次发布提供的是文字栅格化和图片合成,并未记录文字时间轴或动画系统。文字需要运动时,应使用视频或动画渲染器。不要想当然地认为保留动态图片输入,就能获得动态排版控制。
如果希望围绕自己的商品目录或发布系统搭建可靠的图片端点,可以从 AI 生产系统开始。
2026年9月7日







