ConvertPdfDocumentColours 读取 PDF 当前有效修订,通过 IPdfColourTransform 转换原始分量操作数和图像采样,并向独立输出流追加一致的新修订
支持 DeviceGray、DeviceRGB、DeviceCMYK 和 ICCBased 空间中的文本及矢量填充/描边操作符、继承的页面资源、命名默认色彩空间别名、嵌套 Form XObjects,以及使用 8-bit 或 16-bit 分量的原始或通用过滤器图像
内容数组共用一个操作数解析器和图形状态栈,流之间插入空格;整个转换过程中,q/Q、默认色彩空间和分量数始终关联原始源空间
CMYK 操作数直接来自 PDF 内容和图像流,不使用渲染后的 RGB getter;没有配置文件的 DeviceCMYK 源须提供 DeviceCMYKProfile
源 ICCBased 配置文件从原始资源作用域解析;仅支持缺省或默认的 /Range [0 1 ...],图像 /Decode 数组则在转换前应用,并从转换后的图像中移除
16-bit 图像采样保留 PDF 大端字节序;分配采样缓冲区前会验证精确字节几何和目标数据扩展量,不会凭空添加步长或填充字节
PreserveAllSpotColours 默认为 true;否则需在 PreservedSpotColours 中填入解码后的 PDF 着色剂名称,只有所有列出的着色剂都被选中时,Separation 或 DeviceN 空间才会保留
保留的专色操作符、色调函数和资源保持原样;未选中的专色需要专用转换后端,否则报告为不支持
图像模板遮罩和被引用的遮罩数据保持原样;颜色键遮罩、显式遮罩及软遮罩底色分量需要另行制定策略
不支持的范围包括缺少原始分量解码器的 DCT/JPX 图像、1/2/4-bit 图像及其行填充、非默认 ICC 范围、Indexed/Cal/Lab/Pattern 空间、内联图像、渐变函数、Type3 字形程序、注解字典颜色、表单默认外观指令、XFA 颜色内容、透明组、非 normal 混合、叠印,以及图形传递函数或渲染意图
自带资源的 Form 须在裸 sc/scn 操作数前建立色彩空间;共享 Form 或图像若继承到不同的源上下文,会报告为不支持,缓存的失败也会传播到每个调用作用域
FailOnUnsupported 默认为 true,失败时保留目标;设为 false 可独立应用受支持的更新,同时将 Complete 设为 false,部分转换绝不会写入新的 OutputIntent
部分结果可能保留源文件已有的 OutputIntent;OutputIntentWritten 专门表示本次操作是否安装了新的目标声明
完整结果会嵌入传入的目标 ICC 配置文件,并按指定标识写入 OutputIntent;这不代表通过 PDF/X、PDF/A 或其他一致性认证
源流与目标流必须不同;操作会恢复源流位置,准备阶段失败不会修改目标,取消操作保留 EPdfOperationCancelled
发布准备好的结果时通过目标流 API 替换内容;截断或写入异常可能留下部分输出,需要文件原子发布的调用方应先写临时文件,成功后再重命名
加密和已有签名要求先另行准备未加密、未签名的源文档;增量颜色转换不会保留签名有效性
除有效对象读取器预算外,默认还允许每个解码内容/图像流 64 MiB、输出暂存 512 MiB、10,000 条问题报告和深度 64
累积每次更新前,输出预算会保守计入源字节、暂存替换对象和预留的 xref/trailer 开销;序列化前计入完整 trailer 长度,受限输出流会在扩大逻辑大小前拒绝超预算写入
该预算限制的是逻辑输出暂存,不是进程全部内存或分配器向上取整的容量;发布前还会再次检查最终序列化大小
实际 RGB、CMYK 和 ICCBased 图像转换、文本/矢量转换、嵌套 Form、Separation 和 DeviceN 保留、OutputIntent、压缩对象流及 PDF 保存/重新打开/渲染,均已在 Delphi 和 FPC 的 Win32、Win64 目标上验证
ProviderOptions := TPdfLittleCmsOptions.Default; Provider := CreatePdfLittleCmsColourTransform(LibraryPath, ProviderOptions); Options := TPdfDocumentColourOptions.Default; Options.DeviceCMYKProfile := SourceCmykProfile; TargetProfile := CreatePdfLittleCmsGrayProfile(LibraryPath); if not ConvertPdfDocumentColours(Source, Destination, pcsDeviceGray, TargetProfile, Provider, Options, Report, CancellationToken) then raise Exception.Create(Report.ErrorText);
type
TPdfSpotColourNames = array of AnsiString;
TPdfDocumentColourOptions = record
ReadOptions: TPdfActiveObjectReadOptions;
MaxDecodedStreamBytes: Integer;
MaxOutputBytes: Int64;
MaxIssues: Integer;
MaxDepth: Integer;
FailOnUnsupported: Boolean;
PreserveAllSpotColours: Boolean;
PreservedSpotColours: TPdfSpotColourNames;
DeviceGrayProfile, DeviceRGBProfile, DeviceCMYKProfile: TBytes;
OutputIntentIdentifier: string;
class function Default: TPdfDocumentColourOptions; static;
end;
TPdfDocumentColourIssue = record
ObjectNumber: Integer;
Reason: string;
end;
TPdfDocumentColourIssues = array of TPdfDocumentColourIssue;
TPdfDocumentColourReport = record
Succeeded: Boolean;
Complete: Boolean;
ContentStreamsConverted, FormsConverted, ImagesConverted: Integer;
ColourOperatorsConverted, PreservedSpotSelections, PreservedMasks: Integer;
UnsupportedCount: Integer;
OutputIntentWritten: Boolean;
Issues: TPdfDocumentColourIssues;
ErrorText: string;
end;
function ConvertPdfDocumentColours(Source, Destination: TStream;
TargetSpace: TPdfColourSpace; const TargetProfile: TBytes;
Transform: IPdfColourTransform; const Options: TPdfDocumentColourOptions;
out Report: TPdfDocumentColourReport;
CancellationToken: IPdfCancellationToken = nil): Boolean;