Skip to content

feat(pdf): CMYK PDF and Illustrator files β†’ CMYK JPG and TIFF - #1060

Merged
KnifeLemon merged 4 commits into
mainfrom
feat/cmyk-pdf-render
Nov 3, 2026
Merged

KnifeLemon merged 4 commits into
mainfrom
feat/cmyk-pdf-render

Conversation

@KnifeLemon

Copy link
Copy Markdown
Owner

The other half of #1027 (after #1059). A print user's CMYK Illustrator file β†’ JPG came out RGB: AI goes ai β†’ pdf β†’ jpg through PDFium, which renders RGB only. Same for a CMYK PDF.

What changes

  • Detection (Pdf/PdfCmykContent.cs, PdfPig): a document draws in CMYK when its pages (the first 20 selected) use DeviceCMYK colours (k / K, also inside forms), four-channel ICC colour spaces, spot colours (Separation / DeviceN) or CMYK pictures and gradients. Resources are walked with a cap and a cycle check; a PDF PdfPig can't read counts as not CMYK.
  • Rendering (GhostscriptConverter.RenderCmykAsync): for a JPG or TIFF target, a CMYK document is drawn by Ghostscript's tiff32nc (8-bit CMYK) at the preset's DPI, cut to the crop box, anti-aliased. DeviceCMYK values come out as the document gives them (checked: 0.1 / 0.2 / 0.3 / 0.4 β†’ 25 / 51 / 76 / 102).
  • Profile: with a CMYK output intent (PDF/X), Ghostscript renders into it and the picture carries it; otherwise the picture is untagged CMYK, keeping the numbers for the print shop's own profile (e.g. Japan Color 2001 Coated). Ghostscript's own default profile is removed.
  • Encoding: the rendered pages go through the same code as PDFium's (factored out as Encode): quality, resize, _p{n} names, multi-page TIFF, long images, size limits.
  • Unchanged: RGB documents, grayscale presets, other targets (PNG, WebP…), and routes.
  • No silent colour change: when a CMYK file still comes out RGB because Ghostscript isn't installed or failed on it, the result gets a note saying why (notice.cmyk_needs_ghostscript / notice.cmyk_render_failed, all 19 languages).

Tested

CmykRenderTests (19, run here with the real Ghostscript fetched by build/fetch-engines.ps1 -Only ghostscript, none skipped):

  • CMYK PDF β†’ JPG is CMYK, ink values within Β±3, no profile, no note; CMYK .ai β†’ JPG is CMYK;
  • CMYK PDF β†’ multi-page TIFF with a page range; pages stacked into one JPG on ink-free paper;
  • an output intent (SWOP) goes into the JPG byte for byte, values kept;
  • RGB PDF β†’ JPG, CMYK PDF β†’ PNG and a grayscale preset stay as before;
  • without Ghostscript a CMYK PDF β†’ JPG is RGB with the note;
  • detection: CMYK and RGB fills, DeviceCMYK / ICC N=4 / RGB pictures, CMYK vs sRGB output intents, pages outside the selection, broken / missing / truncated PDFs;
  • routes: ai β†’ jpg / tiff stay vector, pdfium, pdf β†’ jpg pdfium.

Engines: the whole project 2064 pass, 0 fail (218 skipped for engines not installed here). App localization 214 pass. dotnet format --verify-no-changes clean.

Not in this PR: CMYK EPS / PS β†’ JPG still goes through Ghostscript's pngalpha (RGB).

πŸ€– Generated with Claude Code

KnifeLemon and others added 3 commits November 3, 2026 21:51
PDFium renders RGB only, so a print file (a CMYK PDF, or an Illustrator file
through its PDF) lost its ink values on the way to JPG or TIFF (#1027). When
Ghostscript is installed and PdfPig finds CMYK content on the selected pages
(DeviceCMYK colours, four-channel ICC spaces, Separation / DeviceN, CMYK
pictures and gradients), PdfiumConverter has the pages rendered with
tiff32nc and encodes them the same way as PDFium's. DeviceCMYK values pass
through unchanged; a CMYK output intent profile is rendered into and
embedded, otherwise the result is untagged CMYK. RGB documents, grayscale
presets, other targets and PCs without Ghostscript keep PDFium's rendering.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A CMYK PDF or AI β†’ JPG/TIFF that falls back to PDFium's RGB because Ghostscript isn't installed, or failed on the
file, now gets a note on the result (notice.cmyk_needs_ghostscript / notice.cmyk_render_failed, in all 19
languages): print work shouldn't change colour unseen. PdfiumConverter.FindGhostscript lets a test see a PC without
Ghostscript. The render tests are now CmykRenderTests, next to the pictures β†’ PDF ones in CmykPdfTests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added the feature New features label Nov 3, 2026
@KnifeLemon
KnifeLemon merged commit d4d4c06 into main Nov 3, 2026
9 checks passed
@KnifeLemon KnifeLemon mentioned this pull request Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant