mapper icon indicating copy to clipboard operation
mapper copied to clipboard

WYSIWYG Printing colours

Open arenol opened this issue 1 year ago • 10 comments

The colours, particularly the cyan colour, is far from realistic compared to the printing colours.

Here's an algorithm that will, reasoably accurate, convert CMYK to RGB that are within the printing gammut:

(c, m, y and k) are in the range 0 to 1, and so are will the rgb's be:

        double r = (1.0 - c) * (1.0 - m * 0.098) * (1.0 - k);
        double g = (1.0 - c * 0.376) * (1.0 - m) * (1.0 - y * 0.070) * (1.0 - k);
        double b = (1.0 - c * 0.109) * (1.0 - m * 0.505) * (1.0 - y) * (1.0 - k);

arenol avatar Nov 23 '24 14:11 arenol

If it works well, I consider it beneficial. The biggest problem I see with the current appearance of 100% blue, for some mapping projects I even adjust its definition to achieve better readability on the display.

krticka avatar Nov 24 '24 13:11 krticka

The colours, particularly the cyan colour, is far from realistic compared to the printing colours.

Fair enough.

Here's an algorithm that will, reasoably accurate, convert CMYK to RGB that are within the printing gammut: ...

Which environoment did you test these formulas with? Are there any references?

This is what I learned in the past:

  • Color "numbers" are usually considered meaningless without naming the color space (color profile). Here, RGB and CMYK are simply device-dependent. References: https://en.wikipedia.org/wiki/CMYK_color_model#Conversion
    https://community.adobe.com/t5/indesign-discussions/formula-to-convert-cmyk-to-rgb-or-rgb-to-cmyk/m-p/2581706
  • "Device dependent" implies that visual results might be quite different for Windows vs. macOS vs. Linux vs. Android vs. printer models and drivers.

The CMYK/RGB conversion isn't part of Mapper's source code, but implemented in the Qt framework. This doesn't mean we couldn't integrate improvements. I'm just stating the fact.

dg0yt avatar Nov 24 '24 16:11 dg0yt

As an illustration.

Top left: OO Mapper (current master), Top middle: Evince displaying a PDF exported from OCAD Viewer in CMYK color space. Top right: LibreMapper with the proposed code change from comment #0. Bottom middle: OCAD Viewer.

image

The patch.

diff --git a/src/core/map_color.h b/src/core/map_color.h
index e3a401eca273..0f2a8baf0844 100644
--- a/src/core/map_color.h
+++ b/src/core/map_color.h
@@ -579,7 +579,11 @@ MapColorCmyk::MapColorCmyk(const QColor& other) noexcept
 inline
 MapColorCmyk::operator QColor() const
 {
-       return QColor::fromCmykF(c, m, y, k);
+       double r = (1.0 - c) * (1.0 - m * 0.098) * (1.0 - k);
+       double g = (1.0 - c * 0.376) * (1.0 - m) * (1.0 - y * 0.070) * (1.0 - k);
+       double b = (1.0 - c * 0.109) * (1.0 - m * 0.505) * (1.0 - y) * (1.0 - k);
+
+       return QColor::fromRgbF(r, g, b);
 }
 
 inline

IMHO, it makes sense to make this change configurable as the differences in map appearance are substantial. In any case, I like the proposal. Thanks!

lpechacek avatar Nov 25 '24 08:11 lpechacek

differences in map appearance are substantial.

And a trivial test:

  1. Export map to PDF in Device CMYK mode.
  2. Add the map as a template, and align it with the existing map.
  3. Hide the map "layer" and show it again.

https://github.com/user-attachments/assets/038ed423-df66-4496-94a7-43c58b5f0686

Mapper should be consistent with itself. :-)

lpechacek avatar Nov 25 '24 10:11 lpechacek

Add the map as a template, and align it with the existing map.

@lpechacek Which GDAL binaries did you use in that test? I wonder how much this step is subject to the PDF backend in GDAL, possibly pulling in lcms2.

@arenol I would really appreciate some reference.

dg0yt avatar Nov 26 '24 08:11 dg0yt

@lpechacek Which GDAL binaries did you use in that test? I wonder how much this step is subject to the PDF backend in GDAL, possibly pulling in lcms2.

GDAL 3.10 on openSUSE Tumbleweed. But the result is roughly the same with a recent Windows build from Mapper CI. My guess is that Poppler interprets the PDF for GDAL on Linux. The PDF has the same color appearance in Evince, Inkscape, QGIS and Scribus, AFAICT.

I don't think that we need to perform full-blown colors management here. Adjust the colors so that they don't hurt user's eyes that much. My choice would be an attempt on replicating the OCAD calculation as users are used to it, so it can be considered as a "industry standard" and therefore widely accepted.

lpechacek avatar Nov 26 '24 12:11 lpechacek

My choice would be an attempt on replicating the OCAD calculation as users are used to it, so it can be considered as a "industry standard" and therefore widely accepted.

For there reference, this is the calculation:

	// OCAD-like transformation
	double r = (1.0 - c          ) * (1.0 - m * 0.00498) * (1.0 - y * 0.00703) * (1.0 - k);
	double g = (1.0 - c * 0.17416) * (1.0 - m * 0.89769) * (1.0 - y * 0.00272) * (1.0 - k);
	double b = (1.0 - c * 0.18420) *                       (1.0 - y * 0.91071) * (1.0 - k);
	return QColor::fromRgbF(r, g, b);

The constants were obtained like this:

  1. Take a map file with sample colors (a custom file with full C,M,Y and a few mixes, plus the IOF MC Print Test Sheet).
  2. Record CMYK combinations for the individual colors from the map file.
  3. Render the map file in OCAD Viewer with "color corrections". (the same corrections are employed for the on-screen display too)
  4. Sample the resulting RGB values from the image using Gimp.
  5. Throw all the CMYK and RGB values into one spreadsheet file. Model the above function, calculate the error squares.
  6. Optimize parameters of the non-linear transformation function with the LibreOffice Calc Solver tool.

lpechacek avatar Nov 27 '24 12:11 lpechacek

As a side note, this is how the color appearance issue was solved in Purple Pen: https://groups.io/g/purple-pen/topic/purple_pen_colors_different/87079064 (TL;DR: "Comparing colors on screen is really unimportant and a waste of time.")

As to my current knowledge, the IOF CMYK colors are in fact unspecified. It seems that there is no "standard CMYK" color model, so the CIE values of the individual process colors are not defined. I think that no one would be surprised these days that we need a geodetic datum to interpret spatial coordinates. The next step is to learn specifying color model along with the color component values.

lpechacek avatar Dec 05 '24 11:12 lpechacek

I really wish the magic formulas from the original post would be backed by an external reference. Similar to us not using magic numbers in the source code.

As to my current knowledge, the IOF CMYK colors are in fact unspecified. It seems that there is no "standard CMYK" color model,

"Device-dependent" might be a sufficient identification of the desired CMYK color space, with 100% Cyan expected to be printed as 100% pure Cyan, regardless of the actual printer.

In need for color management and a device-independent CMYK color space, I would probably choose "ISO Coated v2 300% (ECI)" for European print shops. Combine this with "sRGB" for the computer screen. Pick representative pairs e.g. from gamutmap.com, and you have input for deriving simple formulas as a a proxy for proper color transformations. Not far away from the other two proposals, but with sound vendor-neutral reference points.

MapColorCmyk::operator QColor()

This can be modified to quickly demonstrate the effect, but for proper wiring, we may need to know whether we are rendering to a RGB screen, to a RGB printer driver, or to a CMKY PDF. If the custom CMYK-to-RGB transformation is enforced too early, the color might undergo another unmanaged RGB-to-CMYK transformation, leading to unexpected results. The right hook might be near MapRenderables::draw or PainterConfig::activate. Maybe we also want to modify handling of the MapColor RGB aspect.

Last not least, an animation of the effect: screenshot-rgb

dg0yt avatar Dec 08 '24 12:12 dg0yt

This can be modified to quickly demonstrate the effect, but for proper wiring, we may need to know whether we are rendering to a RGB screen, to a RGB printer driver, or to a CMKY PDF. If the custom CMYK-to-RGB transformation is enforced too early, the color might undergo another unmanaged RGB-to-CMYK transformation, leading to unexpected results.

Confirmed. The above primitive patch breaks PDF export (just in case someone would like to follow my steps). The color corrections indeed need to be made in the places that Kai suggested.

lpechacek avatar May 01 '25 20:05 lpechacek