返回博客
9 分钟阅读
MarkdownToImage

Markdown 转图片 API 教程:用 cURL、Node.js、Python 与 n8n 生成 PNG

从一次可运行的 API 请求开始,学习用 cURL、Node.js、Python 或 n8n 自动把 Markdown 转成 PNG 或 WebP,并可靠保存生成结果。

Markdown 转图片 API 教程:用 cURL、Node.js、Python 与 n8n 生成 PNG

Markdown 转图片 API 教程:用 cURL、Node.js、Python 与 n8n 生成 PNG

偶尔导出一张图片,用浏览器操作就够了。但如果产品需要持续把 AI 报告、更新日志、客服回答或社媒内容转换成统一视觉素材,手动导出很快就会成为瓶颈。Markdown 转图片 API 可以把渲染步骤放进程序:发送 Markdown,选择格式与主题,获取临时 URL 或二进制文件,再把结果保存到应用需要的位置。

本文会搭建一套真正可运行的 MarkdownToImage API 集成。我们先用 cURL 验证请求,再完成 Node.js、Python 和 n8n 版本,并补上快速入门示例通常缺少的生产保护措施。

本文中的接口与限额信息已于 2026 年 8 月 2 日对照官方 API 文档核验。配额与套餐可能变化,估算生产成本前请查看当前价格页

1. 什么时候应该使用 Markdown 转图片 API?

当图片生成属于可重复工作流,而不是偶尔的设计任务时,就适合使用 API。典型场景包括:

  • 把大模型输出转换成可下载的报告图片;
  • 在部署完成后自动生成更新日志卡片;
  • 根据 CMS 字段生成 Open Graph 或社媒卡片;
  • 稳定渲染代码、表格、Mermaid 图表或 KaTeX 公式;
  • 在 n8n、Dify、Make、CI 或内部工具里生成视觉产物。

一次性导出时,浏览器转换器通常更快。如果输入内容已经存在于别的系统中,需要大量复用相同样式,或输出还要自动进入存储、发布和消息发送流程,API 的价值就会明显体现出来。

2. 开始前:令牌与运行环境

登录 MarkdownToImage,在 API Tokens 区域创建令牌。把它当作密码处理:不要写入源码、Markdown 文件、截图、浏览器端 JavaScript 或导出的工作流 JSON。

本地测试时,可以把令牌放入环境变量:

export MARKDOWN_TO_IMAGE_API_TOKEN="mti_your_token_here"

生产环境应使用托管平台提供的加密 Secret。令牌一旦出现在公开仓库或日志中,应立即撤销并重新创建,而不是试图通过删除旧提交来继续使用它。

API 当前提供每月带水印的免费请求额度。去水印或更高用量取决于积分或当时的套餐。实现时请核对官方 API 和价格页面,不要把当前额度硬编码成产品的长期假设。

3. 使用 cURL 发出第一次请求

生成接口接收 JSON,并使用 Bearer 鉴权。下面的请求会生成一张宽 1200 像素、采用 GitHub 深色主题的 PNG:

curl -X POST https://markdowntoimage.com/api/v1/images/generate \
  -H "Authorization: Bearer $MARKDOWN_TO_IMAGE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "markdown": "# Weekly release\n\n- Faster exports\n- Clearer reports\n- One automated workflow",
    "format": "png",
    "width": 1200,
    "quality": 2,
    "theme": "github-dark",
    "mode": "url"
  }'

URL 模式请求成功后,响应中会包含 data.imageUrl。这个地址是临时的:在浏览器打开它只能证明渲染成功,并不等于完成永久存储。应尽快下载文件,再上传到自己的对象存储、CMS 或媒体库。

4. 选择合适的参数与输出格式

请求可以很简单——只有 markdown 是必填字段——但自动化场景应明确指定渲染参数,才能保证结果稳定。

参数作用实用建议
markdownMarkdown 源内容发送前校验长度与必需章节
formatpngjpegwebppdf代码与 UI 用 PNG;网页素材用 WebP;文档用 PDF
width200 至 2560 像素的渲染宽度社媒与报告卡片可从 1200 开始,并用真实内容测试
quality1 至 3 的设备缩放系数建议从 2 开始;数值越高,文件与渲染成本通常越大
theme整体视觉主题固定主题名称,避免版本变化带来视觉漂移
codeStyle代码高亮配色与页面主题配合,确保对比度
fontFamily字体预设用产品实际支持的全部语言测试
modeurlbinaryURL 适合编排;binary 适合直接文件管道

照片类内容且能接受有损压缩时可用 JPEG;代码、图表和清晰 UI 元素优先使用 PNG;所有下游都支持时,WebP 更节省带宽。PDF 虽然使用同一个生成端点,但它属于文档输出,不应当作普通社媒图片处理。

5. Node.js:生成并保存图片

下面的 Node.js 脚本会调用 API、检查 HTTP 响应、下载临时结果并写入真实文件。它使用当前 Node.js 版本提供的全局 fetch

import { writeFile } from "node:fs/promises";

const token = process.env.MARKDOWN_TO_IMAGE_API_TOKEN;
if (!token) throw new Error("MARKDOWN_TO_IMAGE_API_TOKEN is required");

const response = await fetch("https://markdowntoimage.com/api/v1/images/generate", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${token}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    markdown: "# Build report\n\n- Tests: **passed**\n- Deploy: **ready**",
    format: "png",
    width: 1200,
    quality: 2,
    theme: "github-dark",
    mode: "url",
  }),
  signal: AbortSignal.timeout(30_000),
});

if (!response.ok) {
  throw new Error(`Generation failed: ${response.status} ${await response.text()}`);
}

const result = await response.json();
const imageResponse = await fetch(result.data.imageUrl, {
  signal: AbortSignal.timeout(30_000),
});
if (!imageResponse.ok) {
  throw new Error(`Download failed: ${imageResponse.status}`);
}

await writeFile("build-report.png", Buffer.from(await imageResponse.arrayBuffer()));
console.log("Saved build-report.png");

如果这是 Web 服务,应该等永久上传完成后再把任务标记为成功。只保存 API 返回的临时 URL、却没有复制实际文件,会在 URL 到期后变成延迟故障。

6. Python:生成并保存图片

Python 在 URL 模式下同样需要两次请求:先创建渲染,再下载结果。明确设置超时时间,可以避免 Worker 无限等待。

import os
from pathlib import Path

import requests

token = os.environ["MARKDOWN_TO_IMAGE_API_TOKEN"]
payload = {
    "markdown": "# Build report\n\n- Tests: **passed**\n- Deploy: **ready**",
    "format": "png",
    "width": 1200,
    "quality": 2,
    "theme": "github-dark",
    "mode": "url",
}

response = requests.post(
    "https://markdowntoimage.com/api/v1/images/generate",
    headers={"Authorization": f"Bearer {token}"},
    json=payload,
    timeout=30,
)
response.raise_for_status()

image_url = response.json()["data"]["imageUrl"]
image_response = requests.get(image_url, timeout=30)
image_response.raise_for_status()
Path("build-report.png").write_bytes(image_response.content)
print("Saved build-report.png")

用量增加后,建议把这个函数放进任务队列,而不是在面向用户的请求中同步执行长时间渲染。队列可以控制并发与重试,并记录最终存储地址。

7. 在 n8n 中搭建相同工作流

在 n8n 中,把 HTTP Request 节点放在生成或读取 Markdown 的节点之后。令牌应保存到 n8n Credentials,不要直接粘贴进工作流 JSON。

Method: POST
URL: https://markdowntoimage.com/api/v1/images/generate
Authentication: Header Auth
Header name: Authorization
Header value: Bearer {{$credentials.markdownToImageToken}}
Send Body: JSON
Body:
{
  "markdown": "{{$json.content}}",
  "format": "png",
  "width": 1200,
  "quality": 2,
  "theme": "github-dark",
  "mode": "url"
}

再连接第二个 HTTP Request 节点,下载 {{$json.data.imageUrl}} 并启用文件输出,然后把二进制文件发送到 S3、Google Drive、Directus、WordPress、Slack 或其他目标。还要显式配置错误分支,避免鉴权或额度失败时仍然发布空记录。

8. 选择 URL 模式还是 binary 模式?

如果自动化平台擅长处理 JSON,并能继续执行第二次下载,请选择 URL 模式。它适合队列、Webhook 和无代码工作流,但返回地址只会临时保留;官方文档当前标明为 24 小时。

如果希望把一次响应直接流式写入存储,可以选择 binary 模式。它省去第二次 HTTP 请求,但客户端必须正确处理二进制内容、Content-Type、文件扩展名、内存上限以及上传中断后的清理。

无论使用哪种模式,都应该把最终文件保存到自己控制的存储。同时记录请求格式、宽度、主题、源内容 ID、生成时间以及 Markdown 哈希,方便去重和排查事故。

9. 处理 API 错误并避免重复渲染

官方文档列出了这些重要结果:

HTTP 状态含义建议操作
400缺少 Markdown 或参数无效不要原样重试;先修正并校验请求体
401令牌缺失、无效或已撤销停止任务并告警;更换或修正 Secret
429免费额度或积分不可用延迟任务、通知负责人或增加容量
500生成失败或内部错误使用退避策略进行有限次数重试

自动重试应只针对暂时性失败,而不是所有非 200 响应。500 与网络超时可以使用带随机抖动的指数退避。如果连接状态不确定,在重试前先检查应用是否已经为同一内容哈希保存了结果,避免一个逻辑任务产生多次付费渲染。

日志应记录状态码、服务端错误码、任务 ID、尝试次数和延迟,但绝不能记录完整 Authorization Header。

10. 生产环境检查清单

接入真实流量前,请逐项确认:

  • API 令牌保存在服务端加密 Secret 中;
  • 已设置连接超时与总请求超时;
  • 重试次数有限,并使用带抖动的指数退避;
  • Worker 并发符合 API 配额与下游存储能力;
  • 调用前已校验 Markdown 大小与必需字段;
  • 已固定格式、宽度、主题、代码样式和字体;
  • URL 模式结果会立即下载到永久存储;
  • 文件名安全、可预测,不直接信任用户输入;
  • 发布图片时提供合适的替代文本与上下文;
  • 记录用量,并在额度耗尽前告警;
  • 用真实内容测试多语言字体、长代码行、表格、Mermaid 与 KaTeX;
  • 关键发布流程保留人工兜底方案。

先准备一小组有代表性的测试内容。十份真实 Markdown 往往比数百次 “Hello World” 更容易暴露布局问题。

11. 常见问题

API 能否直接把 Markdown 转为 PNG?

可以。向生成接口发送 format: "png" 即可,也可以选择 JPEG、WebP 或 PDF。对于代码、文本、图表和界面截图,PNG 通常最稳妥。

能否从浏览器直接调用 Markdown 转图片 API?

不要在客户端代码中暴露 Secret API Token。应该通过服务器、Serverless Function 或受保护的自动化工作流调用 API,再把已经永久保存的结果返回给浏览器。

如何把 AI 或大模型输出生成图片?

先进行长度、内容与安全检查,再把模型输出的 Markdown 写入 markdown 字段。固定提示词模板和渲染参数,比允许每个回答自行决定布局更容易获得一致卡片。

使用 n8n 是否足够,还是必须写 Node.js 或 Python?

对于生成、下载和上传这类直线流程,n8n 已经足够。需要高并发、自定义幂等、详细可观测性,或要与产品权限和计费紧密集成时,再使用应用代码。

12. 下一步:用一份真实内容测试

选择产品已经在生成的一份 Markdown,直接套用本文的 cURL 示例。扩展工作流前,先检查代码换行、表格、字体和图片尺寸。

第一次渲染达到预期后,打开 MarkdownToImage API 指南,创建只在服务端使用的令牌,把 Node.js、Python 或 n8n 方案接入一个小规模生产测试。最稳妥的上线顺序是:先处理一种真实内容、固定一套视觉预设、接入永久存储和可观测错误处理,再根据数据扩展。

Markdown To Image | Markdown 转图片 API 教程:用 cURL、Node.js、Python 与 n8n 生成 PNG | MarkdownToImage