PDFium Delphi Component Docs

文件 ICC 色彩轉換

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;