Skip to main content
Skip table of contents

Setting Output Intents

📌 Overview

An output intent describes the final destination device you will use to reproduce the color in the PDF, such as the separations printing device. Output intents override working spaces during viewing and printing, but they do not convert the colors in the PDF. You can include output intents when you create PDF/X (or PDF/A) files.

📗 Instructions

Mako uses a property of the IPDFOutput class to specify the output intent when writing a PDF. The IOutputIntent class represents a PDF output intent and provides the create() method that requires several items of information, described below. More detailed information regarding the information needed is described in the PDF specification 1.7 (refer to section 14.11.5).

🪜 Steps

  1. Create an output intent: The IOutputIntent::create() method requires the following information, described here with some examples:

Name

Output intent property

Typical value / purpose

sRGB

SWOP

FOGRA39

registryName

Profile registry

http://www.color.org

http://www.color.org

http://www.color.org

outputCondition

Output condition

sRGB IEC61966-2.1

CGATS TR 001 (SWOP)

FOGRA39

outputConditionIdentifier


sRGB IEC61966-2.1

CGATS TR 001

FOGRA39

subtype

Subtype

One of: GTS_PDFX, GTS_PDFA1, ISO_PDFE1

info

Info

A human-readable text string containing additional information or comments about the intended target device or production condition. Can be left blank.

profile

ICC Profile

An IDOMICCProfile. See code example for creation of this class from a file-based ICC profile.

  1. Set the output intent(s): Set this as the output intent using IPDFOutput::setOutputIntent() or IPDFOutput::setOutputIntents() if setting multiple.

⌨️ Sample Code

The code in the following section created a PDF, shown here as displayed in Acrobat (or Acrobat Reader).

  • The ICC profile used for the output intent is deliberately designed to alter colors in a dramatic fashion, so that it is clear it is being applied.

  • To see the effect on the PDF, you can open it in Adobe Acrobat Reader DC and set Edit > Preferences > Page Display > Use Overprint Preview to 'Always':

With the 'Use Overprint Preview' option set to 'Never'.

With the 'Use Overprint Preview' option set to 'Always'.

Below are extracts of the code in C++ and C#, which is available in full on our GitHub Gists page. See SaveWithOutputIntent.cpp or SaveWithOutputIntent.cs.

C++

C#

CPP
// The ICC profiles
CEDLVector<std::pair<U8String, U8String>> profiles;
profiles.append(std::pair<U8String, U8String>("Probev2_ICCv4.icc", "https://www.color.org/probeprofile.xalter"));
profiles.append(std::pair<U8String, U8String>("GRACoL2006_Coated1v2.icc", "https://idealliance.org"));
profiles.append(std::pair<U8String, U8String>("JapanColor2011Coated.icc", "https://www.xrite.com"));

// Load profile from local storage
const auto iccProfile = IDOMICCProfile::create(mako, IInputStream::createFromFile(mako, R"(..\..\TestFiles\)" + profiles[0].first));

// Output intent metadata
U8String subtype = "GTS_PDFX";
U8String registryName = "http://www.color.org";
U8String outputCondition = profiles[0].first;
U8String outputConditionIdentifier = profiles[0].first;
U8String info = "Output Intent test";

// Create a PDF output set to write PDF/X
auto output = IPDFOutput::create(mako);
output->setPreset("PDF/X-4");

// Create an intent and add to PDF (the primary, and only intent recognized for PDF/X purposes)
auto outputIntent = IOutputIntent::create(mako, subtype, outputCondition, outputConditionIdentifier, registryName, info, iccProfile);
output->setOutputIntent(outputIntent);

// Write PDF/X-compliant PDF
output->writeAssembly(assembly, "OutputIntentExample.pdf");

// Check that the PDF has an output intent
auto testDocument = IPDFInput::create(mako)->open("OutputIntentExample.pdf")->getDocument();
_ASSERT(testDocument->getOutputIntents().size() == 1);

// Demonstration of adding more than one output intent. PDF/X allows it, may suit some custom workflows
COutputIntentVect outputIntents;
outputIntents.append(outputIntent);

// We add two alternates
subtype = "GGS_DUMMY";
registryName = "https://idealliance.org";
outputCondition = profiles[1].first;
outputConditionIdentifier = profiles[1].first;
info = "The GRACoL 2006 Coated v2 from idealliance.org";

// Create an intent and add to list
outputIntent = IOutputIntent::create(mako, subtype, outputCondition, outputConditionIdentifier, registryName, info, iccProfile);
outputIntents.append(outputIntent);

subtype = "GGS_DUMMY";
registryName = "https://www.xrite.com";
outputCondition = profiles[2].first;
outputConditionIdentifier = profiles[2].first;
info = "The Japan Color 2011 profile from xrite.com";

// Create an intent and add to list
outputIntent = IOutputIntent::create(mako, subtype, outputCondition, outputConditionIdentifier, registryName, info, iccProfile);
outputIntents.append(outputIntent);

// Set multiple intents
output->setOutputIntents(outputIntents);

// Write PDF
output->writeAssembly(assembly, "OutputIntentExampleThreeIntents.pdf");

// Check that the PDF has three output intents
testDocument = IPDFInput::create(mako)->open("OutputIntentExampleThreeIntents.pdf")->getDocument();
_ASSERT(testDocument->getOutputIntents().size() == 3);

// Done
C#
// The ICC profiles
var profiles = new List<Tuple<string, string>>();
profiles.Add(Tuple.Create("Probev2_ICCv4.icc", @"https://www.color.org/probeprofile.xalter"));
profiles.Add(Tuple.Create("GRACoL2006_Coated1v2.icc", "https://idealliance.org"));
profiles.Add(Tuple.Create("JapanColor2011Coated.icc", "https://www.xrite.com"));

// Load profile from local storage
var iccProfile = IDOMICCProfile.create(mako, IInputStream.createFromFile(mako, Path.Combine(@"..\..\..\..\TestFiles\", profiles[0].Item1)));

// Output intent metadata
var subtype = "GTS_PDFX";
var registryName = "http://www.color.org";
var outputCondition = profiles[0].Item1;
var outputConditionIdentifier = profiles[0].Item1;
var info = "Output Intent test";

// Create a PDF output set to write PDF/X
using var output = IPDFOutput.create(mako);
output.setPreset("PDF/X-4");

// Create an intent and add to PDF
var outputIntent = IOutputIntent.create(mako, subtype, outputCondition, outputConditionIdentifier, registryName, info, iccProfile);
output.setOutputIntent(outputIntent);

// Write PDF
output.writeAssembly(assembly, "OutputIntentExample.pdf");

// Check that the PDF has an output intent
var testDocument = IPDFInput.create(mako).open("OutputIntentExample.pdf").getDocument();
if(testDocument.getOutputIntents().size() != 1)
    throw new ApplicationException("Output intent count not equal to 1");

// Demonstration of adding more than one output intent. PDF/X allows it, may suit some custom workflows
CEDLVectIOutputIntent outputIntents = new CEDLVectIOutputIntent();
outputIntents.append(outputIntent);

// We add two alternates
subtype = "GGS_DUMMY";
registryName = "https://idealliance.org";
outputCondition = profiles[1].Item1;
outputConditionIdentifier = profiles[1].Item1;
info = "The GRACoL 2006 Coated v2 from idealliance.org";

// Create an intent and add to list
outputIntent = IOutputIntent.create(mako, subtype, outputCondition, outputConditionIdentifier, registryName, info, iccProfile);
outputIntents.append(outputIntent);

subtype = "GGS_DUMMY";
registryName = "https://www.xrite.com";
outputCondition = profiles[2].Item1;
outputConditionIdentifier = profiles[2].Item1;
info = "The Japan Color 2011 profile from xrite.com";

// Create an intent and add to list
outputIntent = IOutputIntent.create(mako, subtype, outputCondition, outputConditionIdentifier, registryName, info, iccProfile);
outputIntents.append(outputIntent);

// Set multiple intents
output.setOutputIntents(outputIntents);

// Write PDF
output.writeAssembly(assembly, "OutputIntentExampleThreeIntents.pdf");

// Check that the PDF has three output intents
testDocument = IPDFInput.create(mako).open("OutputIntentExampleThreeIntents.pdf").getDocument();
if (testDocument.getOutputIntents().size() != 3)
    throw new ApplicationException("Output intent count not equal to 3");

// Done

☑️ Conclusion

Setting output intents in PDFs is crucial for ensuring accurate color reproduction on the final output device. By using the IPDFOutput and IOutputIntent classes in Mako, users can specify detailed output conditions, such as color profiles and registry names, to match their production needs. The provided sample code demonstrates how to implement these settings effectively.

📚 Additional Resources

If you need additional help, see our API documentation for detailed information on class/method usage, or raise a support ticket via our customer portal.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.