PDF 色彩保真工程实践【3】上手实践:工程结构、依赖集成与一键构建运行

本文是系列文章的第 3 篇。方案已经清楚,这一篇我们动手把工程跑起来:看懂目录结构、安装好依赖、用脚本完成依赖准备、构建和运行,并读懂 --verify 输出的每一项 PASS。

进行一切之前,请先下载完整源码:https://github.com/AmyLin2013/pdf-cmyk-image

本篇你将学到

  • 工程整体结构与各模块职责;
  • 如何用 vcpkg 一键准备 libtiff / zlib;
  • 如何集成福昕 PDF SDK 与试用授权、运行时 DLL;
  • 如何构建、运行,并读懂 --verify 的输出。

环境要求

  • Windows x64;
  • Visual Studio 2022:
    • v143 工具集;
    • "使用 C++ 的桌面开发"工作负载;
    • Windows 10/11 SDK;
  • Windows PowerShell 5.1 或 PowerShell 7;
  • Git;
  • 用于准备 libtiff / zlib 的 vcpkg(脚本可自动引导)。
  • 可访问 GitHub 与 vcpkg 下载源的网络环境;
  • Foxit PDF SDK 11.1 Windows x64 试用包。

vcpkg 可以预先安装,也可以由脚本自动克隆和初始化。

工程结构总览

复制代码
cmykImage/
├─ CmykImage.sln                 VS2022 解决方案(仅 x64)
├─ CmykImage/                    源代码与工程文件
│  ├─ main.cpp                   命令行入口
│  ├─ CommandLine.*              命令行参数解析
│  ├─ TiffCmykReader.*           libtiff 解码 CMYK 像素 + 提取 ICC
│  ├─ IccProfileParser.*         检查 ICC 关键头部字段(size / acsp / CMYK)
│  ├─ CmykImageEncoder.*         zlib 压缩 + ReaderCallback
│  ├─ FoxitPdfObjectFactory.*    构造 ICC 流 / ColorSpace / Image XObject
│  ├─ PdfPageResourceManager.*   注册 XObject 到页面资源
│  ├─ PdfContentStreamManager.*  追加绘制指令到内容流
│  ├─ PdfCmykImageInserter.*     顶层编排:插入流程
│  ├─ PdfCmykVerifier.*          重新打开输出 PDF 并逐项校验
│  ├─ FoxitSdkContext.*          SDK 初始化 / 释放(RAII)
│  └─ Sha256.*                   自包含 SHA-256
├─ third_party/                  福昕 SDK 与 libtiff/zlib(脚本落地)
├─ scripts/                      依赖准备与构建脚本
├─ samples/input/                示例 CMYK TIFF
└─ docs/                         设计与验证文档

设计上每个模块单一职责 :解码、校验、压缩、对象构造、资源挂接、内容绘制、编排、校验彼此解耦,方便逐块阅读与测试。

第一步:准备 libtiff / zlib 依赖

依赖通过 vcpkg 动态链接(x64-windows)引入,一条脚本搞定:

powershell 复制代码
powershell -ExecutionPolicy Bypass -File scripts\prepare_dependencies.ps1

脚本会:安装 tiffzlib,然后把头文件、导入库(Debug/Release)与运行时 DLL拷进 third_party/libtiffthird_party/zlib,并记录依赖版本。

⚠️ 避坑点 :新版 vcpkg 的 zlib 产物名可能是 z.lib / zd.libz.dll / zd.dll

而非老版本的 zlib.lib / zlib1.dll。工程链接名与脚本已按新命名适配。若你自己的

vcpkg 版本不同,注意核对导入库名称。

第二步:集成福昕 PDF SDK

福昕 SDK 不随开源仓库分发,需要自行申请试用包https://developers.fuxinsoft.cn/free-trial/,再用脚本拷入:

powershell 复制代码
powershell -ExecutionPolicy Bypass -File scripts\copy_foxit_sdk.ps1 -SdkRoot <解压后的_foxitpdfsdk_目录>

脚本会把 SDK 头文件、fsdk_win64.libfsdk_win64.dll,以及试用授权文件(gsdk_sn.txtgsdk_key.txt)拷入 third_party/foxit 的对应位置。

🔐 合规提示:源码中不硬编码任何真实授权码,运行时从授权文件读取。授权文件与库文件都不应提交到公开仓库。

第三步:构建

用 VS2022 直接打开 CmykImage.sln 选择 x64 构建,或用脚本:

powershell 复制代码
powershell -ExecutionPolicy Bypass -File scripts\build_release.ps1   # 或 build_debug.ps1

构建完成后,一个后置事件会自动把运行时 DLL(福昕、tiff、zlib 及其依赖)和授权文件拷到可执行文件目录,省去手动复制。

⚠️ 避坑点 :MSBuild 传入的 $(OutDir) 带尾部反斜杠,若直接拼进 PowerShell 命令,反斜杠会转义引号导致"路径含非法字符"。脚本里对参数做了 Trim('"').TrimEnd('\')处理,这个坑第 6 篇还会细说。

最短验证路径

完成依赖和 SDK 准备后,可以直接执行:

powershell 复制代码
powershell -ExecutionPolicy Bypass -File scripts\run_tests.ps1 -Configuration Release

该脚本会自动:

构建 Release x64;

使用内置 CMYK TIFF 样例;

生成 samples\output\cmyk_result_Release.pdf;

运行完整的 --verify 校验。

需要同时验证 Debug 和 Release 时,可省略 -Configuration Release。

以下命令均需在仓库根目录 pdf-cmyk-image 下执行。

如果下载的是 ZIP,请先完整解压,避免直接在压缩包预览目录中运行脚本。

第四步:运行并读懂输出

powershell 复制代码
build\x64\Release\CmykImage.exe `
  --input-tiff samples\input\sample_cmyk.tif `
  --output-pdf samples\output\result.pdf `
  --create --overwrite --verify
  • --create:源 PDF 不存在时新建空白页;
  • --overwrite:允许覆盖输出;
  • --verify:保存后重新打开并逐项校验。

运行成功你会看到一连串 PASS,最后是 RESULT: All verifications passed.

复制代码
PASS: TIFF is valid CMYK.
PASS: TIFF ICC Profile is valid CMYK ICC.
PASS: Inserted image as ImCMYK1 (ICCBased CMYK).
PASS: PDF Image uses ICCBased color space.
PASS: ICC stream N equals 4.
PASS: ICC Alternate is DeviceCMYK.
PASS: PDF ICC profile matches TIFF ICC profile.
PASS: PDF CMYK pixels match TIFF CMYK pixels.
...
RESULT: All verifications passed.

这些 PASS 不只是证明程序可以运行:校验器还会重新打开输出 PDF,对解码后的 ICC Profile 和 CMYK 像素分别计算 SHA-256,并与源 TIFF 数据逐字节对应。------第 6 篇会展开。

常用命令行参数

参数 说明
--input-pdf <path> 源 PDF(省略并配合 --create 时新建空白页)
--input-tiff <path> 输入 CMYK TIFF(必填)
--output-pdf <path> 输出 PDF(必填)
--page <n> 目标页码(0 基)
--x --y <pt> 图像左下角坐标
--width --height <pt> 绘制尺寸;<=0 时按像素/纵横比自动推算
--create / --overwrite / --verify 新建 / 覆盖 / 自校验
--license-dir <path> 授权文件(gsdk_sn.txt / gsdk_key.txt)目录(默认为 exe 所在目录)

常见错误与排查

错误现象 常见原因 处理方式
找不到 tiff.libz.lib 尚未准备依赖 运行 prepare_dependencies.ps1
找不到 fsdk_win64.lib 未拷贝 Foxit SDK 运行 copy_foxit_sdk.ps1
SDK initialization failed 授权文件缺失、过期或路径错误 检查 EXE 目录或使用 --license-dir
缺少 DLL 后置事件未执行或依赖目录不完整 检查 copy_runtime.ps1 输出
output PDF already exists 未指定覆盖 增加 --overwrite
TIFF ICC 警告 无 ICC 或 ICC 不是 CMYK 换用带有效 CMYK ICC 的 TIFF
找不到 MSBuild VS2022 C++ 工作负载未安装 通过 Visual Studio Installer 补装

小结

依赖准备、SDK 集成、构建、运行四步走,脚本把重复劳动都自动化了。跑通之后,我们就可以深入核心实现------下一篇开始拆代码。

下一篇预告

第 4 篇《核心实现(上):从 TIFF 解码到 Flate 流构造》,我们从 libtiff 读出 CMYK 像素与 ICC,压缩成 Flate 流,讲清"把数据变成 PDF 流对象"的关键策略。


关于本系列

相关推荐
程序员与背包客_CoderZ5 分钟前
高性能分布式KV存储引擎RocksDB入门与C/C++编码实战
c语言·开发语言·数据库·c++·分布式·分布式数据库·rocksdb
进击的_鹏7 分钟前
从零开始的 Redis 学习
服务器·数据库·c++·redis·缓存
_Narcissus_1 小时前
链表算法题和静态链表
数据结构·c++·笔记·算法·链表·ai·力扣
布莱克6051 小时前
C++拷贝构造与拷贝赋值运算符的区别详解
开发语言·c++
啦啦啦啦啦zzzz2 小时前
时间轮定时器
linux·服务器·网络·c++·定时器
此生决int3 小时前
深入理解C++系列(15)——AVL树
开发语言·c++
一只旭宝3 小时前
预约系统版本2(pyhton+flask可视化版本)
服务器·数据库·c++·笔记·python·flask
爱奥尼欧3 小时前
10.C++ string 实现详解
java·开发语言·c++
会周易的程序员4 小时前
软件接入大模型实现 Agent —— 从原理到 C++ 落地完全指南
c++·人工智能·物联网·架构·agent·工业协议·mcp
hetao17338374 小时前
2026-08-21~23 hetao1733837 的刷题记录
c++·算法