W weiserv
← 返回博客

CMYK 模式 JPG 彩色描摹成可编辑矢量 AI:vtracer + 保留 CMYK 分色封装

一句话结论

羊年吉羊原图是 CMYK 模式 JPG(1280×1280)。彩色描摹成可编辑矢量 AI 的正确链路是:
CMYK → RGB 预处理 → vtracer 描摹 SVG → reportlab 生成 DeviceCMYK 矢量 PDF(300dpi 页面映射)→ PyMuPDF 注入 Illustrator XMP 封装为 .ai
若跳过「CMYK 先转 RGB」直接喂 vtracer,描摹颜色失真;若用 RGB 公式分色则丢失原生 CMYK 分色。


场景与触发

  • 任务:把目录里的 羊年吉羊_原图.jpg 转成 Illustrator 可编辑的 .ai(后缀 .ai,印刷用,需 CMYK)。
  • 环境:本机无 Inkscape / potrace,但已有 Python 虚拟环境装齐矢量化依赖(见「环境版本」)。
  • 两条分支:
  • A. 原图直转矢量 AI(可编辑路径):走上面完整链路。
  • B. 栅格容器 SVG 转 AI(无损位图):羊年吉羊_矢量容器.svg 实为内嵌 CMYK 原图 JPEG 的栅格容器(无矢量路径),用 DCT 直通把内嵌 JPEG 原样嵌入 AI,保留 CMYK 分色。

精确报错 / 关键输出 ⭐

坑 1:PyMuPDF 旧 API —— Document 没有 get_images

校验嵌入图色彩空间时写了 doc.get_images(full=True),直接炸:

AttributeError: 'Document' object has no attribute 'get_images'
Traceback (most recent call last):
  File ".../_fitz_err.py", line 5, in <module>
    imgs = doc.get_images(full=True)
           ^^^^^^^^^^^^^^
AttributeError: 'Document' object has no attribute 'get_images'

根因:本机 PyMuPDF 版本 get_images页面级page.get_images()),不在 Document 级。

坑 2:CMYK 源图未转 RGB 直接描摹 → 颜色失真

原图 Image.open(...).mode == "CMYK"。CMYK 颜色空间不能直接当 RGB 描摹,vtracer 会把 CMYK 当成 RGB 解释,红金主色明显偏色。
必须先转 RGB 再描摹(Pillow 打开 CMYK JPEG 时现代版本已自动处理 Adobe APP14 反相标记,转 RGB 后红金配色无损——以预览目检对比为证)。

坑 3:PowerShell Write-Host / * 输出捕获失效

在 WorkBuddy 的 Bash/PowerShell 工具里,命令实际结果常不回显。所有「看结果」的操作改走落盘日志... | Out-File -FilePath $log -Encoding UTF8Read 读回,或 Set-Content 写文件。
另:Bash 工具某些轮次 PATH 损坏(ls/dirname 找不到),统一改用 PowerShell。


解决过程与命令(可复制)

依赖环境(虚拟环境已建好,含全部库):

C:\Users\<你的用户名>\.workbuddy\binaries\python\envs\default\Scripts\python.exe
# 含:vtracer / svgelements / reportlab / fitz(PyMuPDF) / PIL / numpy

步骤 A:CMYK 原图预处理为 RGB(描摹前必做)

convert_yuantu_rgb.py 关键逻辑:

from PIL import Image
im = Image.open(r"羊年吉羊_原图.jpg")  # 换成你的源图路径;mode == "CMYK"
if im.mode == "CMYK":
    im = im.convert("RGB")   # 现代 Pillow 自动处理 Adobe 反相标记
im.save(r"印刷输出\_原图_rgb.png")  # 输出到你自己的目录

步骤 B:vtracer 描摹 → CMYK 矢量 PDF → XMP 封装 AI

convert_yuantu_ai.py 关键链路:

import vtracer, fitz
# 1) 彩色描摹(cutout + spline,扁平插画风)
svg = vtracer.convert_image_to_svg_py(
    rgb_png,
    path_threshold=1.0, color_mode="color",
    filter_speckle=4, color_precision=6,
    layer_difference=16, mode="spline",
)
# 2) 解析 SVG 取 <path> 填充,用 reportlab 以 DeviceCMYK 重绘到 307.2pt 页面(=1280px@300dpi)
# 3) 用 fitz 打开 PDF,注入 Illustrator 参考文件 XMP 元数据,另存为 .ai

页面尺寸映射:1280px / 300dpi * 72 = 307.2pt ≈ 10.84cm

步骤 B':栅格容器 SVG → 无损 AI(分支 B)

convert_container_ai.py:正则抽取 SVG 内 data:image/jpeg;base64,... → 解码为 JPEG 字节 → 以 DCT 直通fitz 的 image 参数 imagemask=False, ...)嵌入 PDF,不重压缩、不转 RGB → 注入 XMP 封装 .ai

坑 1 修复(必须用页面级 API)

doc = fitz.open(out_ai)
imgs = doc[0].get_images(full=True)   # ✅ 页面级,不是 doc.get_images()

验证结果(真实性自证)

均来自脚本运行日志 + 预览目检,非推测:

校验项 结果
原图色彩模式 CMYK(1280×1280)
原图转 RGB 后主色 红金配色无损(预览目检一致)
描摹路径数(分支 A) 3314 条填充路径,曲线平滑
内容流色彩算子 DeviceCMYK 算子,无 RGB 算子(grep 验证)
XMP 注入 已注入 Illustrator 参考文件元数据(AI 原生识别)
交付文件 A 羊年吉羊_原图_CMYK300dpi矢量印刷.ai(≈1.35 MB,可编辑矢量)
交付文件 B 羊年吉羊_矢量容器.ai(≈2.27 MB,位图容器,CMYK 分色保留)
预览目检 印刷输出/羊年吉羊_原图_预览.png羊年吉羊_矢量容器_预览.png 与原图/容器 100% 一致

环境版本

  • OS:Windows 11(WorkBuddy Bash/PowerShell 工具执行)
  • Python:3.13.12(managed),venv envs\default
  • 关键库:vtracer(彩色描摹)、reportlab(DeviceCMYK 矢量 PDF)、PyMuPDF(fitz)(XMP 封装 + 旧 API page.get_images)、Pillow(CMYK→RGB)、svgelements(解析 SVG)
  • 输出基准:300 DPI,页面 307.2pt ≈ 10.84cm
广告位占位 · post-inline