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 色彩空間
保留的特別色運算子、色調函式與資源維持完整;未選取的特別色需要專用轉換後端,會回報為不支援
影像樣板遮罩與參照的遮罩資料維持完整;色鍵遮罩、明確遮罩與軟遮罩 Matte 分量需要各自的處理策略
不支援的範圍包括缺少原始分量解碼器的 DCT/JPX 影像、1/2/4-bit 影像與列填補、非預設 ICC 範圍、Indexed/Cal/Lab/Pattern 色彩空間、內嵌影像、漸層函式、Type3 字形程式、註解字典色彩、表單預設外觀指令、XFA 色彩內容、透明群組、非正常混合、疊印,以及圖形轉移函式或繪製意圖
具有自身資源的 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 長度,有上限的輸出串流也會在擴大邏輯大小之前拒絕超限寫入
此限制約束邏輯輸出暫存,並非所有程序記憶體或記憶體配置器向上取整的容量;發佈前也會再次檢查最終序列化大小
已在 Win32 與 Win64 上,以 Delphi 和 FPC 驗證實際 RGB、CMYK、ICCBased 影像轉換、文字/向量轉換、巢狀 Form、Separation 與 DeviceN 保留、OutputIntent、壓縮物件串流,以及 PDF 儲存/重新開啟/繪製
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;