Codia
返回文章列表

从扁平 PDF 到结构化 UI:深入 PDF-to-Visual-Struct 流水线

Engineering2026-04-23

PDF 的本质问题

PDF 无处不在——产品规格书、财报、合规表单、遗留设计交付物——但它们几乎对自动化毫不友好。一份 PDF 本质上是一串扁平的绘制指令:"移动到 (120, 440),用 Helvetica 12 渲染字形 'H',向右移动,渲染 'e'……"。里面没有按钮、卡片或标题的概念,没有层级结构,甚至连"词"这种概念都不稳定。

PDF to Visual Struct 就是为弥合这道鸿沟而生。把 PDF 发送到 POST /v1/open/pdf_to_design,你会得到与 Codia Studio 同源的 Visual Element Schema:一棵层级分明的 JSON 元素树,每个节点都带有类型、边界框、布局配置与样式规格。这棵树对机器可读、对设计师可读,只差一次变换就能跑通代码。

本文详细说明 API 的工作方式、返回的 Schema,以及你能在其之上构建什么。

调用 API

请求是一次 multipart/form-data POST,无需 SDK。

bash
curl 'https://api.codia.ai/v1/open/pdf_to_design' \ -H 'Authorization: Bearer {codia_api_key}' \ -H 'Content-Type: application/json' \ --form 'pdf_file=@"invoice.pdf"' \ --form 'page_no="0"'

两个输入:PDF 文件,以及从 0 开始的页码。如果你有 40 页文档、要全部转换,就循环并发调用——API 按页无状态,并发压力下表现良好。官方指标为单文档 100+ 页、50+ 种元素类型、单页响应低于 2 秒。实际上多数单页 PDF 在文件进入入口后 600–1200 ms 即可返回。

响应结构

顶层是这样的:

json
{ "configuration": { "scalingFactor": 1, "baseWidth": 1940, "measurementUnit": "px" }, "pages": [ { "visualElement": { /* 根元素 */ } } ], "size": { "height": 1080, "width": 1940 } }

configuration 说明坐标如何解释。baseWidthmeasurementUnit 是参考系——如果你要改变视口尺寸,按比例缩放每个边界框即可。size 是布局求解后归一化的画布。

每一页都有一个 visualElement 根节点。沿 childElements 递归深度遍历即可得到整篇文档。每个节点都有同样的核心字段:

json
{ "elementId": "pdf_page_1", "elementName": "PDF Document Page", "elementType": "Panel", "displayName": "First Page", "displayOrder": 0, "boundingBox": [0, 0, 595, 842], "layoutConfig": { "positionMode": "Normal", "flexibleMode": "Absolute" }, "styleConfig": { "widthSpec": { "sizing": "FIXED", "value": 595 }, "heightSpec": { "sizing": "FIXED", "value": 842 }, "backgroundSpec": { "type": "COLOR", "backgroundColor": { "rgbValues": [255, 255, 255] } } }, "processingMeta": { "surfaceArea": 501490, "detectionScore": 0.92, "textContainerized": false }, "childElements": [] }

重点字段如下:

  • elementType —— 强类型标签。PanelTextImageIconButtonTableChart 以及数十种其他类型。这是让输出可操作的关键:你可以基于它直接生成 HTML、Flutter 组件或 React 组件,而不再依赖启发式规则。
  • boundingBox —— 基础坐标系下的 [x, y, width, height]。用于在绝对布局中定位子元素,或在后处理时检测重叠与分组。
  • layoutConfig —— 描述父容器如何摆放子元素(流式、flex 行/列、还是自由定位)。语义与 Figma auto-layout 对齐,回写 Figma 非常轻松。
  • styleConfig —— 宽高策略(FIXEDFILL_CONTAINERHUG_CONTENT)、背景、描边、圆角、排版。概念与 CSS 足够接近,代码生成器可以直接输出干净的样式表。
  • processingMeta.detectionScore —— 检测置信度 0–1。生成下游产物前过滤低置信节点非常有用。

流水线在做什么

把 PDF 转成这份 Schema 并不是一次模型调用,而是一条短流水线:

  1. 光栅化 + 提取。 解析 PDF 流,取出文本段、矢量路径与嵌入位图。扫描页则并行进入 OCR。
  2. 版式分析。 视觉模型将页面切分为区域——页眉、正文、边栏、插图、表格、题注——为每块赋予粗类型。Panel 的边界来自这里。
  3. 元素检测。 区域内更密集的模型识别单独 UI 元素——按钮、图标、表单控件、图表系列。elementType 来自这一步。
  4. 文本聚合。 把字形位置聚合成词、行、段,挂到最近的容器元素上。
  5. Schema 组装。 构建层级、解析父子链接、计算每个元素的样式、把坐标归一化到 baseWidth

第 2、3 步占延迟预算的大头,前后都很轻量。

能在其上构建什么

Schema 刻意保持通用。实际案例:

设计导入。 一键把遗留 PDF 规格书转成可编辑的 Figma 页面。因为布局配置对齐了 Figma auto-layout 语义,自动布局会正确重建。

遗留现代化。 拿一份 500 页的 PDF 手册,生成响应式网页版。每一页变成一条路由;元素类型驱动组件选择。

视觉回归测试。 在两个构建中渲染同一页基线,分别通过 API,比较元素树。元素级差异对字体替换与子像素抗锯齿远比像素差异稳定。

带布局感知的 RAG。 给 PDF 做检索索引时,丢掉原始文本拉平结果。按元素分块,保留父子关系,就能回答"第 4 页的 CTA 是什么"或"第 11 页第二张表的第三列是什么",无需模糊启发式。

图表提取。 图表节点携带足够的元数据(轴标、系列颜色、分组文本),可以直接提升为实时图表组件,而不是渲染成截图。

关于准确率

实际检测质量取决于 PDF 来源、文本清晰度和版面复杂度。产品设计类 PDF 通常更容易解析;扫描法律文件和手写表单更难,OCR 噪声更多、detectionScore 更低,需要过滤。

快速上手

  1. codia.ai/dashboard/developer 获取 API Key。
  2. 对手边任意 PDF 跑上面那条 curl
  3. 用你喜欢的语言遍历响应树——Schema 是纯 JSON,不需要 SDK。
  4. 如果你想跳过解析、直接拿到 Figma 文件,可以使用基于同一条流水线构建的 PDF to Design Figma 插件

完整参考、请求/响应格式与错误码在开发者文档。如需更高速率或私有部署,请联系 [email protected]——流水线以隔离容器交付,满足企业数据驻留需求。

PDF 不会消失。过去十年,它一直是设计自动化最顽固的最后一公里。给它一份干净、强类型的结构,是把它重新变成一等公民的第一步。

#pdf#visual-struct#api#design-automation#schema