Page 1 of 1

Merging RGB and CMYK into CMYK

Posted: 2018-07-18T04:57:22-07:00
by teambuktu
Hello ImageMagick community ;)

This is my first post and before I start I want to thank you guys for all your effort and the enormous amount of information on this site!

I'm developing a web-to-print-solution, and need to merge two sorts of images:

RGB -> Convert into ISO coated V2.

CMYK -> Take it as it is, if the icc profile is correct (ISO coated V2).

The images are treated as layers that can be positioned on a canvas. There can be formats like transparent PNGs, JPEGs (CMYK or RGB) and a few others. The images are soft proofed while they are being edited. Once the user has finished a design, a PDF is generated.

All that stuff works like a charm, however I'm kind of new to color managment, and I ran into an issue, that is tough to solve (at least when it comes to precision).

Since there are quiet a few transformations that must be done with the final design (images are scaled, rotated, and so on), I am using the RGB colorspace for composing the final image, which then is converted into CMYK and placed in a PDF.

Now I'm trying to find the most precise way of converting CMYK into RGB (for composition purposes) and then back into CMYK. In an ideal scenario the CMYK color values would remain unchanged.

There are two significant impacts on the scenario:

1. The CMYK contains NO colours with channel BLACK > 0%

Conversion to RGB (without rendering intent) and back gives identical results. Perfect!

2. The CMYK contains colours with channel BLACK > 0%

Conversion to RGB cannot be done without rendering intent, since the channel BLACK would just be dropped without having been taken into account for the conversion.
Once the rendering intents are applied the majority of color values will have changed after rendering forth (to RGB) and back (to CMYK).

So today I tried to extract the channel BLACK as GRAYSCALE and use it somehow with the RGB composition (I'm not happy with the results and also I'm not sure if that is a sensible approach)...

Basically I try to find a conversion of a CMYK-image that has colors with BLACK > 0% without rendering intent (to preserve CMY), but at the same time I need either the rendering intent for preserving the channel BLACK as good as possible or the solution I did not find yet :)

Since the image is part of a whole composition of images (basically the print master), I can not just copy the extracted channel BLACK back. Placing it at the right position in the composition also would not solve the problem (since graphics in the composition may overlap). So I am wondering if the extracted channel BLACK can somehow be useful for the composition in RGB colorspace.

Or maybe there is some type of approach where all Black channels are merged into one image (like the RGB composition) and then copied back into the final CMYK composition.

This is now exactly the point at which I felt like asking what you guys would do, or if you ran into the same problem before ;)

Best :)

Re: Merging RGB and CMYK into CMYK

Posted: 2018-07-18T11:18:51-07:00
by snibgo
Your RGB input images: are they linear RGB, non-linear sRGB, or something else? Do they have embedded profiles?

Do your input CMYK images have embedded profiles? If not, why not?

Using a linear RGB colorspace for scaling, rotating etc is sensible.

From your comments about the Black channel of CMYK, I guess you are using IM "-colorspace". I suggest you use profiles instead.

I'll assume your inputs all have profiles. If they don't, I suggest you (a) tell your suppliers to include profiles or (b) assign a profile of your choice, which will probably be wrong (but your customers may not notice).

For conversion to linear RGB, I would use Elle Stone's profiles at ... files.html
For example, "-profile sRGB-elle-V2-g10.icc" will give you a linear version of sRGB. She also has linear versions of wider colorspaces.

Re: Merging RGB and CMYK into CMYK

Posted: 2018-07-22T11:15:38-07:00
by teambuktu
Please excuse my delayed answer, I was lost in colorspace... :lol:

I'll try to break my problem down, and be more precise.

The user can design a printing template and upload the following formats (for the beginning):


If a CMYK-JPEG or CMYK-PDF is uploaded, the server checks whether the correct CMYK profile exists, otherwise the CMYK profile is assigned.

If an image is not in CMYK colorspace then sRGB is assumed.

The images are stored online just as they were uploaded, with the exception, that a JPEG is extracted from every PDF (only 1 Page PDFs allowed for now).

There are the following color-management use-cases:

1. The user selects an uploaded file and places it on a browser canvas.

The view simulates the CMYK appearance (relative rendering intent, but the intent could be a user's choice later on). I'm aware that this is not going to be perfect, unless only calibrated screens are used. However, the goal is to simulate the appearance as close as possible. For an exact preview, the user can download a PDF which is precise (ISO coated V2 profile included, and exact color values).

For simulating the image-appearance to look like CMYK in the browser I do the following:

case A: CMYK-files get converted to sRGB (ISOcoated_v2_eci.icc to sRGB2014.icc).

case B: SRGB-files make a roundtrip and are converted to CMYK (relative rendering intent), and the go throuh the handler of case A.

So now the appearance of specific colors gets close to CMYK and (most important) matches across all shown images/graphic elements. The user can now add layers, rearrange the graphics, add text, set a background and so on.

Once the design is finished, the user wants to download a PDF

2. Now all the information from the online designer gets passed to the server.

The server now does all the merging of layers into one image and a final print master is generated.

Actually I found out, that ImageMagick's composite is capable of quiet a few crazy things, and that the merging can be done in CMYK as well ;) All sRGB-files can be processed after being converted (relative rendering intent) to CMYK and the merging with already existing CMYK images works very well. This is awesome!

Maybe the anti-aliasing around text elements (transparent background PNG) generated in the frontend could be improved. I'll look into that, there are some good filters (but this part is also a question of perforamance)...after all the professional designer can always design the whole template in Photoshop and the web-to-print-solution is supposed to help non-professionals customize items (templates must be curved, the designer is actually in 3d, and the canvas(es) where the user places his graphics are only used internally).

3. User-picked color values

I came across a problem, which I tried to tackle with different approaches:

How to softproof (in a web browser) background or text color that is being selected in CMYK, even though the frontend is not capable of handling CMYK?

A. For background colors I do the following:

- Take the CMYK value as the user entered it, and generate an image (Imagick PHP wrapper):

$image = new Imagick();

$image->newImage($print_width, $print_height, new ImagickPixel($cmyk_string));


I do not use a profile, since the CMYK values must be exactly the ones, the user entered, and will be part of the print master, to which the profile ISO coated V2 will be assigned anyways.

This works great so far.

B. For text elements the problem is different:

- The text elements are passed to the server as base64-encoded PNG-files, so they are in sRGB. Since the graphic is not created by the server, I need to make sure, that after converting to CMYK, the color value is the same, that the usered entered. So it's kind of like CMYK being transmitted via sRGB.

After quiet a few approaches I found a pretty good way (once again Imagick PHP wrapper):




This was the only way that worked for me so far. I need a conversion like:

Code: Select all

	var $c,$m,$y,$k;
	$r = $r/255;
	$g = $g/255;
	$b = $b/255;
	$max = Math.max($r,$g,$b);
	$k = 1 - $max;
	if ($k == 1) {
		$c = 0;
		$m = 0;
		$y = 0;
	else {
		$c = (1 - $r - $k) / (1 - $k);
		$m = (1 - $g - $k) / (1 - $k);
		$y = (1 - $b - $k) / (1 - $k);

transformImageColorspace is exactly what I was looking for. I also tried stuff with GraphicsMagick (partly used on the server for security reasons):

gm convert /input.tiff -colorspace RGB -colorspace CMYK /output.tiff

However, this only works well when the expected BLACK is at 0% (user input).

For example, if I get RGB(0, 153, 153), transformImageColorspace (see above) will convert this to the expected CMYK(100%,0%,0%,40%)

gm convert on the other hand converts to CMYK(100%,40%,40%,40%), it always adds the BLACK channels percentage as a min value somehow...I don't know if it is a bug, or if don't understand it well enough yet.

How would transformImageColorspace (from Imagick) be written on the command line?

C. Softproofing the user-picked values:

For this problem I created a lookup table with a reduced number of colours (to keep it small), so each time the user picks (in a colorpicker) or enters a CMYK value, another RGB value can be found to simulate the CMYK appearance. This works well so far, but especially for darks colors my lookup table shows its limitations. Here is how I created it:

I converted a png with a subset of all colors (for each pixel one RGB combination) to a CMYK tiff as described in 3.B, and then I opened the tiff in Photoshop, converted it back to sRGB-PNG (with black point compensation activated).

For each CMYK value the user picks the corresponding RGB-Value can be found in the table (since I use a subset of all colors, I round a little bit).

Calculating those values server-side would not be an option (a request for each color conversion is not acceptable ;)), at the sime time I did not find a way of interpreting profiles via Javascript yet, so I guess the conversion can't be done without a lookup table.

I'm sure my workflow can be improved, so maybe somebody knows, if things can be done more accurate or straight-forward? :)

Re: Merging RGB and CMYK into CMYK

Posted: 2018-07-22T14:11:47-07:00
by snibgo
teambuktu wrote:If a CMYK-JPEG or CMYK-PDF is uploaded, the server checks whether the correct CMYK profile exists, otherwise the CMYK profile is assigned.
Otherwise which CMYK profile is assigned?
teambuktu wrote:If an image is not in CMYK colorspace then sRGB is assumed.
So if a user uploads an image in AdobeRGB colorspace, you wrongly assume it is sRGB? Or you prohibit any RGB colorspaces except sRGB?
teambuktu wrote:case A: CMYK-files get converted to sRGB (ISOcoated_v2_eci.icc to eciRGB_v2.icc).
No. eciRGB is not sRGB. They are different colorspaces.

I don't know GraphicsMagick or IMagick, and can't comment on those aspects.

Re: Merging RGB and CMYK into CMYK

Posted: 2018-07-22T14:36:23-07:00
by teambuktu
No. eciRGB is not sRGB. They are different colorspaces.
Oh, my bad, that was a mistake (copy & pasted the wrong filename ;)), I meant: sRGB2014.icc
Otherwise which CMYK profile is assigned?
Iso Coated V2 is the profile that is if it is a different profile, then right now a CMYK-to-CMYK-conversion will be made. If a profile does not exist, but the file is in CMYK colorspace, then Iso Coated V2 is assigned to the file.
So if a user uploads an image in AdobeRGB colorspace, you wrongly assume it is sRGB? Or you prohibit any RGB colorspaces except sRGB?
Right now I am converting these files as well, as I call convert and use " -profile sRGB2014.icc" on the input file. I figured this could do no harm, if sRGB2014.icc has already been assigned and therefore handles all RGB cases (no profile, sRGB2014.icc, different sRGB or RGB profile)
Thank you for pointing this out, I guess for the RGB-Input there is still some testing required.