Embed ICC color profile in PDF
Asked Answered
H

2

11

I am generating a PDF where all the graphics are drawn in \DeviceRGB in the sRGB color space. I would like to convert the PDF into a different Color Profile using an ICC profile and embed the ICC profile, but I can't find a good tool to do this.

I have tried ImageMagick, but that rasterizes the PDF which is undesirable, and I have tried using Ghostscript. But while that converts the colors, it doesn't embed the ICC profile.

Is there any tool or library (preferably Java or Scala) available for Linux that does what I want?

The Ghostscript commands I have tried are:

gs -o cmyk.pdf -sColorConversionStrategy=CMYK -sDEVICE=pdfwrite \
   -dOverrideICC=true -sOutputICCProfile=CoatedFOGRA27.icc \
   -dRenderIntent=3 in.pdf

and

gs -dSAFER -dBATCH -dNOPAUSE -sDEVICE=pdfwrite -ColorConversionStrategy=CMYK \
   -dProcessColorModel=/DeviceCMYK -sOutputICCProfile=CoatedFOGRA27.icc \
   -sOutputFile=cmyk.pdf in.pdf 

and several variations of the above. I have tried both Ghostscript version 9.10 and 9.16.

Hamate answered 23/7, 2015 at 15:17 Comment(2)
You profile, CoatedFOGRA27.icc, is indeed located in the directory where you execute your shell command? Otherwise, it must be in one of Ghostscript's default search paths, as reported by gs -h.Nickelson
yes, it is int he directory where I execute the command.Hamate
N
7

Use Ghostscript v9.16 or higher:

Read its documentation about ICC color profile support, available here:

Here's a possible command to convert the color space and embed the ICC profile:

gs -o cmyk-doc.pdf      \
   -sDEVICE=pdfwrite    \
   -dOverrideICC=true   \
   -sDefaultCMYKProfile=/path/to/mycmykprofile.icc \
   -sOutputICCProfile=/path/to/mydeviceprofile.icc \
   -dRenderIntent=3     \
   -dDeviceGrayToK=true \
    input-doc.pdf

(-dRenderIntent : possible arguments are 0 (Perceptual), 1 (Colorimetric), 2 (Saturation), and 3 (Absolute Colorimetric).)

Caveats

If you look at a PDF file on screen (or on paper, when printed) converted with above command and use a:

  • non-calibrated monitor/screen;
  • non-calibrated print device;
  • non-calibrated room illumination; or
  • PDF reader which cannot handle embedded ICC profiles, then

you may be disappointed. Using the wrong ICC profile or paper type that does not match the one expected by the output profile can also lead to issues.

Nickelson answered 23/7, 2015 at 16:41 Comment(4)
gs -version: GPL Ghostscript 9.16 (2015-03-30) To check for the ICC profile I uncompressed the pdf and searched for ICCBased and the name of the profile I used.Hamate
@KurtPfeifle This looks like this command should not embed the color profile. Also, I can confirm this method shows just "ColorSpace: DeviceCMYK" (for a table cell fill color that was RGB before the conversion). Also, I had to add -sProcessColorModel=DeviceCMYK for the command to finish without an error and -sColorConversionStrategy=CMYK to actually convert RGB colors I had. I use gs version 9.26 .Blackmarket
@VarunJoshi, I doubt I can add anything useful to that answer by KenS. Indeed, only a small subset of color management options is supported for pdf output.Blackmarket
-sDefaultCMYKProfile has no effect - it is related to the input (which is not CMYK); -sOutputICCProfile and -dRenderIntent have no effect unless rasterization would happen; -dDeviceGrayToK - just the same, probably; -dOverrideICC=true is generally undesirable and has no effect since the question is about DeviceRGB input.Blackmarket
B
1

AFAIU, Ghostscript 9.12-9.27 is unable to do what you expect.
But you might be able to partially achieve your goals:

  • Try UseDeviceIndependentColor.
    This won't embed your profile, and won't convert colors to your profile. But it would make you colors "colorimetrically defined" and would embed some icc profile. If your aim is to "preserve" colors, that might work for you.

  • Try PDF/X-3 output, embed "Output Intent" icc profile.

  • Try to adjust the DefaultRGB colorspace - note the following phrase in the docs:

    If a user needs an non trivial color adjustment, a non trivial DefaultRGB color space must be defined

    (I've never tried this.)

  • Try collink. (I've never managed to make this work.)

A toy example

Original file:

Colorbar foxit.PNG

The gs command:

 gswin64c -dPDFX -dBATCH -dNOPAUSE -dHaveTransparency=false -r20 
  -dProcessColorModel=/DeviceCMYK -sColorConversionStrategy=UseDeviceIndependentColor 
  -sDefaultRGBProfile="default_rgb.icc" -sOutputICCProfile="cmyk_des_renderintent.icc" 
  -dRenderIntent=1 -dDefaultRenderingIntent=/Perceptual -sDEVICE=pdfwrite 
  -sOutputFile=colorbar_v1.pdf PDFX_IntCmyk.ps Colorbar.pdf

The output looks like this in Adobe Acrobat (it honors embedded "Output Intent" icc profile): enter image description here

Same file in Foxit Reader (it ignores embedded "Output Intent"): enter image description here

What's happening here:

  • The cmyk_des_renderintent.icc profile, as documented in "Ghostscript 9.21 Color Management", is designed such that different intents output different colors:
    • "Perceptual" rendering intent (0) outputs cyan only,
    • "RelativeColorimetric" intent (1) outputs magenta only
    • "Saturation" rendering intent (2) outputs yellow only.
  • -dHaveTransparency=false makes sure that the 2nd page would get rasterized (due to the presence of a tikz pic with transparency)
  • -r20 makes sure rasterization would be clearly visible (due to just 20dpi)
  • -sOutputICCProfile="cmyk_des_renderintent.icc" -dRenderIntent=1 makes rasterizer produce magenta output.
    • Note that OutputICCProfile parameter is not mentioned in current docs, since this (9.27 docs are a bit outdated).
    • RenderIntent is also undocumented in this context. It only affects rasterization as well.
  • -dDefaultRenderingIntent=/Perceptual puts said intent to metadata, alongside "Output Intent icc profile". This makes Acrobat draw everything in cyan.
  • -sDefaultRGBProfile="default_rgb.icc" is a placeholder for possible experiments with input icc profiles. Same default is set if this parameter is omitted.
    If you know that your input profile is sRGB (but it is not embeded - the pdf is plain \DefaultRGB), it might be a good idea to explicitly specify the profile here. Even though sRGB is the default.
  • I use modified gs/lib/PDFX_def.ps from the Ghostscript repo, which embeds cmyk_des_renderintent.icc as the "Output Intent".

You can find all files used in this experiment here. There are several other experiments as well. I've created them trying to understand how Color Management works in gs. I hope they shed some light on the subject. There's also a comparison with Adobe Acrobat "Convert Colors" tool. AFAIU, it does exactly what you expect.

When it comes to Color Management for pdf output, KenS (gs dev) usually says "the pdfwrite device goes to extreme lengths to maintain color specifications from the input unchanged in the output". It looks like they do not really focus on things like conversion from one profile to another in this case. Well... This is hardly "the most requested" feature.

Blackmarket answered 8/7, 2019 at 19:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.