Change Image's CMYK value inside a PDF to hide for example the Cyan color from it

Product: PDFNet Windows
Product Version: 9.4

Please give a brief summary of your issue:
Trying to edit CMYK value of an image

Please describe your issue and provide steps to reproduce it:
I’m trying to reproduce something a bit like we you have in the Webviewer demo where you can hide color separation on an image, for example, I can hide the Cyan component and all images in the PDF will have their Cyan value at 0.
I’ve tried multiple things, like the example bellow, but I cannot find a way to make it work, what am I doing wrong?

std::vector<std::string> separationsToHide{"Cyan"};
while ((element = reader.Next()) != NULL)
{
	const auto elementType = element.GetType();
	if (elementType == PDF::Element::e_image || elementType == PDF::Element::e_inline_image)
	{
		GState graphicState = element.GetGState();
		ColorSpace imageColorSpace = element.GetImageColorSpace();
		auto strokeColor = graphicState.GetStrokeColor();
		auto fillColor = graphicState.GetFillColor();
		auto SDFObject = imageColorSpace.GetSDFObj();

		if (imageColorSpace.GetType() == ColorSpace::e_device_n)
		{
			if (SDFObject.GetAt(1).IsArray())
			{
				const auto numberOfComponents = SDFObject.GetAt(1).Size();
				for (auto i = 0; i < numberOfComponents; ++i)
				{
					bool cmykChanged = false;
					auto object = SDFObject.GetAt(1).GetAt(i);
					auto objectType = object.GetType();
					const auto componentName = std::string(SDFObject.GetAt(1).GetAt(i).GetName());
					if (componentName == "Cyan" && ContainerUtils::contains(separationsToHide, std::string("Cyan")))
					{
						fillColor.Set(0, 0);
						strokeColor.Set(0, 0);
						cmykChanged = true;
					}
					if (componentName == "Magenta" && ContainerUtils::contains(separationsToHide, std::string("Magenta")))
					{
						fillColor.Set(1, 0);
						strokeColor.Set(1, 0);
						cmykChanged = true;
					}
					if (componentName == "Yellow" && ContainerUtils::contains(separationsToHide, std::string("Yellow")))
					{
						fillColor.Set(2, 0);
						strokeColor.Set(2, 0);
						cmykChanged = true;
					}
					if (componentName == "Black" && ContainerUtils::contains(separationsToHide, std::string("Black")))
					{
						fillColor.Set(3, 0);
						strokeColor.Set(3, 0);
						cmykChanged = true;
					}

					if (cmykChanged)
					{
						graphicState.SetFillColor(fillColor);
						graphicState.SetStrokeColor(strokeColor);
						continue;
					}
				}
			}
		}
		writer.WriteElement(element);
		continue;
	}
}
1 Like

Hi Nico,

You can get individual separations using PDFDraw or PDFRasterizer, but we currently don’t have a way to work with and toggle individual separations using our Core SDK.

As you noted, we do have this as an option with our WebViewer, and you could use that to handle your image.

Hi @kmirsalehi ,
Thank you for this answer!
Could you show me both examples of how to use PDFDraw and PDFRasterizer to get individual separations, please?
It feels like we can toggle the separation using the example I shared with my initial post, but it works for everything but images, maybe there’s something I’m missing? It’s working for text, path, etc.
I would love to be able to find a way to hide/show process color (CMYK mostly).

To summarize your first answer, PDF::Elements of type e_image do not support GraphicState changes, is that a correct statement?