📌 Overview
This article explains how to remove embedded ICC-based color profiles from a PDF using the Mako SDK. This is often necessary when profiles cause unexpected rendering results, such as outputting CMYK instead of pure Black (K).
Issue Description
A customer reported that while they could remove embedded profiles from images, they were struggling to do the same for PDF files. Specifically, a PDF with an embedded profile was rendering in CMYK, whereas the version without the profile correctly output only K.
💡 Solution
The solution involves using a custom transform that targets both images and color spaces. By extending a custom transform to iterate through the PDF page content, you can identify and remove ICCBased color space profiles.
🪜 Steps
-
Implement a Custom Transform: Create a class inheriting from
ICustomTransform::IImplementation. -
Target Color Spaces: Within the transform, identify
ICCBasedcolor spaces. -
Apply to Document: Iterate through the pages of the document and apply the transform to the page content.
⌨️ Sample Code
The following approach demonstrates how to use a custom transform to strip profiles. Full code can be found at RemoveEmbeddedProfiles.cs.
class RemoveEmbeddedProfilesTransform(IEDLClassFactory factory)
: ICustomTransform.IImplementation
{
public override IDOMImage transformImage(
ICustomTransform.IImplementation genericImplementation,
IDOMImage image,
CTransformState state) =>
SubstituteImageColorSpace(factory, image) ??
genericImplementation.transformImage(null, image, state);
public override IDOMColorSpace transformColorSpace(
ICustomTransform.IImplementation genericImplementation,
IDOMColorSpace colorSpace,
CTransformState state) =>
GetReplacementDeviceColorSpace(factory, colorSpace) ??
genericImplementation.transformColorSpace(null, colorSpace, state);
}
private static IDOMImage? SubstituteImageColorSpace(
IEDLClassFactory factory,
IDOMImage image)
{
using var replacementColorSpace = GetReplacementDeviceColorSpace(factory, image);
if (replacementColorSpace == null) return null;
var substitutedImage = image.getImageWithSubstitutedColorSpace(factory, replacementColorSpace);
if (substitutedImage == null || IDOMImage.isEqual(image, substitutedImage)) return null;
return substitutedImage;
}
private static IDOMColorSpace? GetReplacementDeviceColorSpace(IEDLClassFactory factory, IDOMImage image)
{
using var frame = image.getImageFrame(factory);
using var sourceColorSpace = frame.getColorSpace();
return GetReplacementDeviceColorSpace(factory, sourceColorSpace);
}
private static IDOMColorSpace? GetReplacementDeviceColorSpace(
IEDLClassFactory factory,
IDOMColorSpace? sourceColorSpace)
{
if (sourceColorSpace == null ||
sourceColorSpace.getColorSpaceType() != IDOMColorSpace.eColorSpaceType.eICCBased) return null;
using var iccBasedColorSpace = IDOMColorSpaceICCBased.fromRCObject(sourceColorSpace);
if (iccBasedColorSpace == null) return null;
var processChannels = IColorManager.get(factory).getNumComponentsForICCBasedSpace(iccBasedColorSpace);
return processChannels switch
{
1 => IDOMColorSpaceDeviceGray.create(factory),
3 => IDOMColorSpaceDeviceRGB.create(factory),
4 => IDOMColorSpaceDeviceCMYK.create(factory),
_ => null
};
}
☑️ Conclusion
By targeting color spaces within a custom transform, you can effectively remove embedded ICC profiles from PDF content, ensuring consistent rendering behavior across different files.
📚 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.