Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CMYK Support #283

Closed
troopa81 opened this issue Feb 27, 2024 · 33 comments
Closed

CMYK Support #283

troopa81 opened this issue Feb 27, 2024 · 33 comments

Comments

@troopa81
Copy link

troopa81 commented Feb 27, 2024

CMYK Support

Date 2024/02/27

Author Julien Cabieces (@troopa81)

Contact julien dot cabieces at oslandia dot com

maintainer @troopa81

Version QGIS 3.38/3.40 (with a Qt 6 version)

Summary

CMYK support has been requested for a long time.

QGIS.org is actually funding Qt developments so it could support CMYK colorspace PDF rendering (you can take a look at this article if you want to know more about CMYK). This QEP describes the needed modifications into QGIS in order to be able to generate PDF layout/report using CMYK defined colors.

At the moment, it is already possible to use CMYK color in QGIS symbology BUT the CMYK defined color is then converted into RGB, resulting in a loss of color data and color shifts. The goal of this proposal is to be able to write native CMYK colors in PDF so it could be printed using CMYK components, not RGB components.

Limitations

Only in Qt 6

As it will be a new Qt feature, it won't be available in Qt 5 and will land in Qt 6 only (exact version is still to be determined). As a consequence, complete support for CMYK in QGIS will only be available with QGIS 4.XX version (or maybe a Qt6 preview non-official-3.XX-version).

However most of the development described hereafter is Qt 5 compatible and I hope it will be integrated into QGIS 3.38.

Only in PDF

Current Qt development will allow to:

  • load/save CMYK image
  • Apply basic modifications on this CMYK image
  • paint into a PDF with native CYMK colors (without RGB to CMYK conversion)

But it will not be possible to paint natively in a CMYK image, and therefore on the screen. The reasons are that it would bring too much effort, complexity and further maintenance in Qt code. As a result, on-screen rendering or image rendering will convert on the fly the possible CMYK defined colors to RGB colorspace BEFORE the rendering.

Proposed Solution

Set project to CMYK colorspace

CMYK color definition is only meaningfull if it is done respectfully to the color space targeted for printing. If a user wants to work with CMYK colors, he needs to select the ICC profile of the device he plans to print on. This has to be done in the early stage of its project definition, meaning in project properties.

From the Styles tab of project properties, it will be possible to set :

  • The color model of the project : RGB or CMYK;
  • The printer ICC profile. A QgsFileWidget, enabled only when color model is CMYK, will allow to select the ICC profile to be used for this project. It will also inform the user if the loaded file is a valid profile or not.

The profile will be added as an attached file using QgsProject::createAttachedFile method.

A default ICC profile, still to be determined, would be embedded into QGIS and set when CMYK mode is enabled.

If CMYK color is used and QGIS is built upon Qt 5, a message will be displayed so user know that CMYK support will be incomplete.

CMYK widget selector

Color picker has to be modified to allow selecting a color in CMYK color space. I propose to add a combo box in order for the user to select the color model, either RGB/HSV or CMYK.

colorpicker_rgb
color picker in RGB mode

colorpicker_cmyk
color picker in CMYK mode

Current color profile should be displayed to let the user know that color on-screen output will be adapted to current selected color profile (see rendering).

Color preview

color_preview
color preview

If color is a CMYK defined color, HSV/RGB informations will be replaced with CMYK ones.

default color

Default color initialization (here for instance) has to be adaptated to return a CMYK color if CMYK mode is enabled within the project.

Expressions

In expressions, it is possible to build a color using some color functions (color_cmyk(a), color_rgb(a)..). All these methods convert the defined color in rgb and return a string representation of it. As discussed above, we want to avoid the CMYK to RGB conversion so that we can write CMYK colors in our generated PDF.

In order to keep API compatibility, I propose to add another set of color functions which will return a plain QColor instead of a string representation of it. for each color_XXXX function, I propose to deprecate it and add a qcolor_XXXX instead.

The default string representation of QColor has to be implemented to match the current one as best as possible, so it will be easy to migrate, although it will not be possible to be idempotent (qcolor_rgb and qcolor_rgba will get the same representation while alpha is not displayed with color_rgb version).

Implement Color ramp

A CMYK color interpolation algorithm has to be implemented using CMYK components without converting to RGB. A classic linear interpolation will be applied on each component like it is done for RGB interpolation algorithm.

Generating PDF

Print services often requires PDF/X format as input. This PDF format is specially adapted for printing because it enforces some already existing PDF features being mandatory when it comes to printing. Fox example, embedding fonts to be sure that the rendering would be the same for printer for instance.

Qt does not support this format at the moment. It does not allow setting the color profile for the output PDF file neither . These two limitations will have to be removed if we want to be able to print a correct CMYK PDF file.

PDF/X format (when available) will be choosen over default PDF 1.4 version when the user selects a CMYK color model in his project.

Rendering

As described above, when choosing to work in CMYK mode, we target a specific printer for the generated PDF layout/report. In that case, users may want to have an on‑screen preview of how their document’s colors will look, when reproduced on this specific device.

Qt applies a default "naïve" transformation for colors defined in CMYK mode when it comes to draw on an RGB device.

In order to get closer to what the color will actually look like on the printing device, we need to use QColorSpace to load selected ICC profile file, and create a QColorTransform to transform CMYK defined colors from the selected ICC profile to the sRGB color space QColorSpace::SRgb, which Qt operates in by default.

As a consequence, when CMYK mode is enabled, we need to convert all colors before painting.

Here is the proposed solution to do so, in order to be the less invasive as possible in rendering code.

Color transform & Render context

QgsColorTransform will wrap Qt classes QColorSpace and QColorTransform and provide a method to make conversions.

class QgsColorTransform
{
    /**
	  * Build a color transform that transform a color or image from \a colorProfile file name to the 
	  * Qt default sRGB color space
	  */
	QgsColorTransform( const QString& colorProfile );
	
	/**
	  * Returns transformed \a color according to this transformation
	  */
	QColor transform( QColor color );
	
	/**
	  * Returns transformed \a image according to this transformation
	  */
	QImage transform( QImage image );
}; 

QgsMapSettings and QgsRenderContext will own an instance of this object, retrieved from QgsProject for the former and transferred to the later in the QgsRenderContext::fromMapSettings method.

Additionally, This class could also define other helper methods to transform QGIS classes which have colors (QgsSymbolLayer, QgsTextFormat, QgsPropertyCollection)

Vector layer

Indentifying color attributes

In order to be able to transform colors dynamically, we need to be able to identify symbol layer color attributes. To achieve this, QgsSymbolLayer class and those which inherits from it should use the Q_PROPERTY macro to expose theirs attributes as properties.

These classes are not QObject classes so the Q_GADGET macro should be added.

EDIT: This part is still under discussion. An alternative could be to let children classes implement a applyColorTransform method (using maybe an helper method taking array of colors as arguments).

Applying the color transformation

The transformation should take place in the QgsSymbol::startRender method which, if a color transform has been defined in the render context, will :

  • run through all the symbol layers,
  • retrieve the color properties using QMetaObject/QMetaProperty
  • read the color
  • if the color is defined as CMYK, apply the transformation and write the property.
Data defined property

When applying color transformation, a new QgsColorTransformer implementing the QgsPropertyTransformer interface will be added on every data defined color properties.

This class will apply the given color transformation to the property value if it is a CMYK defined color.

Image symbol layer

Symbol layers using images (QgsRasterFillSymbolLayer) will have to transform their image (if this one is a CMYK one) using the QgsColorTransform stored in the render context in their startRender methods.

Image reading/loading is done at rendering (because it could depend on a per feature data dependency for instance) and rely on QgsImageCache to avoid reading the image from disk for every feature (here for instance).

As a consequence, QgsImageCache::pathAsImage will take an additionnal QgsColorTransform parameter in order to return a CMYK image transformed.

We assume here that the image color profile will be identical to the one selected for the project. If not, QGIS will raise a warning message.

QgsLinePatternFillSymbolLayer and QgsPointPatternFillSymbolLayer generate their own image thanks to color attributes, so nothing more should be done once we expose the color attributes as properties.

QgsSVGFillSymbolLayer cannot support CMYK SVG and transform them. Indeed, SVG Tiny 1.2 only supports RGB colors and is the only version supported in Qt. It looks like it is possible with SVG Color specification 1.2 though, but it would be a long road before being integrated into Qt.

Raster layer

As it will not be possible to paint natively into a CMYK image, it will not be possible to generate CMYK image into a CMYK output PDF. So, there is no point in defining CMYK colors for raster layer.

We could consider develop soft-proofing in order to transform raster RGB working colors to CMYK space and then to screen device, so we can have a better estimation about how raster would look like when printed. This option has been developed in software like Krita or GIMP but I am not not sure that this would be something that QGIS users are interested in. For now, I consider it beyond the scope of this QEP.

Labels

The same approach as for vector layers should be used for labels. Inside QgsPalLayerSettings::startRender QgsTextFormat will be converted and a QgsColorPropertyTransformer will be added to data dependencies.

Other map layers

The same approach as for vector layers will be used in order to properly deal with others map layers (QgsMeshLayer, QgsGroupLayer, QgsAnnotationLayer, ...) going through the same steps :

  • identifying color properties and color data defined properties
  • modify them before rendering

This could represent a lot of work and could also be impossible for some layer type. QgsMapLayer should advertise whether or not color transform is supported by this map layer so that QGIS will display a warning message if his project contains map layers not supported, and CMYK mode is enabled.

class QgsMapLayer
{
    .
	.
	

    /**
	  * Returns TRUE if this map layer support on-the-fly color transformation
	  */
	bool supportColorTransform() const = 0;
}; 

Layout objects

The same approach as vector layers will be used. Inside QgsLayoutItem::paint, color properties will be converted before the call to the draw() method and then restored to their initial value after.

Tests

Automatic tests will be added in order to check that PDF output is consistent with what is expected, using the qpdf and the technique akin to vector selective masking one.

Affected Files

  • qgsmaplayer.h
  • qgsmaprendererjob.cpp
  • qgssymbol.cpp
  • qgssymbollayer.h/cpp (and inherited classes)
  • qgsfillsymbollayer.h/cpp
  • qgslayoutitem.h/cpp (and inherited classes)

Performance Implications

These modifications will have no impact on QGIS when CMYK mode is disabled. When enabled, it will only cost the color transformation which is not significant.

Backwards Compatibility

Nothing will break backward compatiblity.

Issue Tracking ID(s)

Votes

(required)

@nyalldawson
Copy link
Contributor

In order to be able to transform colors dynamically, we need to be able to identify symbol layer color attributes. To achieve this, QgsSymbolLayer class and those which inherits from it should use the Q_PROPERTY macro to expose theirs attributes as properties.

Why not just add a virtual method "applyColorTransform" and let each subclass decide how best to handle this? It would make it much cleaner for eg the raster/svg subclasses which need the extra logic.

@frspp
Copy link

frspp commented Feb 27, 2024

Thanks!

few notes:
In my workflow the (CMYK) pdf will be anyways imported to Indesign and there I can & will assign a icc profile anyways so in that sense choosing a specific ICC CMYK profile in QGIS is not a must.

If document color mode is CMYK would be very useful to see warning if there is any RGB colors in use.

IMO Color mode belongs to Document properties (like in Indesign), not into Styles.

@eurojam
Copy link

eurojam commented Feb 27, 2024

I would agree to @frspp: In my previous workflows done with ArcMap the assignment of icc profile was done in Illustrator.

@troopa81
Copy link
Author

Why not just add a virtual method "applyColorTransform" and let each subclass decide how best to handle this? It would make it much cleaner for eg the raster/svg subclasses which need the extra logic.

To have a more generic approach, avoid duplicate code which are error prone, ease maintenance if we want to change the way we transform color.

@troopa81
Copy link
Author

@eurojam @frspp Thanks for you comment, that the kind of user workflow details I am looking for.

If you don't set the ICC profile in QGIS, you cannot have an on-screen estimated rendering of what it would look like on paper.

Maybe you don't care but how do you manage to choose correctly your color for your map ?

Krita for instance offers the option to select the ICC profile for the document.

@eurojam
Copy link

eurojam commented Feb 27, 2024

I can describe one of my previous workflows when I used ArcMap. The goal was to make a paper map, for example "geology map". Our customer has a list of color values in CMYK for each geology unit displayed in the map.

In ArcMap there is no need to define or asign the color model to the project. If you choose a color for "unit 1" you will have three color options: RGB, HSV and CMYK. In the CMYK dialog I will enter the values given for unit 1 (see image below...)

grafik

After finishing the map and Layout the next step starts, postprocessing in Adobe Illustrator which starts with the export of the map (layout). Depending on the export format, ArcMap offers different color spaces (CMYK for PDF, AI, EPS)...

grafik

Preparing the final print version will be done in Adobe Illustrator, which has a lot of possibilites in PDF formats, ICC profiles and so one.

grafik

I am not sure, if QGIS should cover all theese steps?

@troopa81
Copy link
Author

@eurojam Thank you for the workflow description

Setting ICC profile is interesting for 2 things:

  • Writing it in PDF output file
  • On-screen rendering

Like you said, the first one could be done with another tool, even though it would be better to have it directly set by QGIS else user would have to be informed that there is another needed step to have a fully compliant CMYK PDF.

Regarding the second one...

Our customer has a list of color values in CMYK for each geology unit displayed in the map

IMHO the tricky point is here because the CMYK color has to be defined regarding a given colorspace i.e the ICC profile used for printing. In your situation, you get the color and ICC profile from a customer so you don't really care about on-screen rendering but I can imagine that some users would like to fine pick the CMYK and check an overall rendering as close as possible as what it look like on a paper.

I don't know if such user really exists (if so, please raise your hand 🙋 ) and if this is needed

I am not sure, if QGIS should cover all theese steps?

Me neither 🤷‍♂️ , I would say yes !

@frspp
Copy link

frspp commented Feb 27, 2024

@troopa81 I can imagine that some users would like to ... check an overall rendering as close as possible as what it look like on a paper.
Yes, everyone likes WYSIWYG :)

I would assume CMYK view without ICC would give a good color match to general printing on coated paper which has a wide color gamut (I mean wide on cmyk scale; such as Fogra39 profile; total ink around 350% I recall).
--> I would suggest that if user has not selected ICC, preview with some "generic" CMYK coated ICC profile such as Fogra39.

And if map will be printed on uncoated paper then the designer should itself know that he/she needs to preview with uncoated ICC (such as Euronewspaper26), as the total ink is only around 240% I recall and by that the color space/gamut is much narrower.

@nyalldawson
Copy link
Contributor

@troopa81

I really like the rest of the proposal, but I strongly disagree with a property based approach for color handling

have a more generic approach, avoid duplicate code which are error prone, ease maintenance if we want to change the way we transform color.

On the contrary, going with a qt based introspection is likely to lead to ongoing issues. My arguments against would be:

  1. We leave behind the security of compile time checks
  2. We are relying on qt specific functionality. While we get a lot of benefits from qt, experience has taught me that in cases where we can avoid qt-isms and stick (without loss of performance/ functionality) with standard libraries we should. By using standard c++ we are sticking with mainstream approaches, which means less likelihood of issues and higher chance of optimisations in the compiler, and no risk of qt deprecating things we've come to rely on.
  3. The property system is pretty clunky for access via python
  4. Using introspection rather then a virtual method makes the code less maintainable. Eg I can't use an ide to find places where the property is accessed. (It also breaks static analysis tools)

@troopa81
Copy link
Author

troopa81 commented Feb 28, 2024

@nyalldawson This is an implementation detail and I can live with a virtual method (which could call a function which would transform an array of given color members) but I would like to avoid as much as possible things like this or that where IMHO, there is too much copy-paste code.

  1. We leave behind the security of compile time checks

I get your point but it is a classic use of reflection mecanism. Q_PROPERTY define statically a member with a pair of getter/setter, and the code will go through QColor only properties to read/write QColor, so I don't really see what compile time checks we would miss.

  1. We are relying on qt specific functionality. While we get a lot of benefits from qt, experience has taught me that in cases where we can avoid qt-isms and stick (without loss of performance/ functionality) with standard libraries we should. By using standard c++ we are sticking with mainstream approaches, which means less likelihood of issues and higher chance of optimisations in the compiler, and no risk of qt deprecating things we've come to rely on.

I would be in favor of relying less on qt-isms but what exactly is the policy here, because I count more than 300 Q_PROPERTY in QGIS code. It looks like we don't use QMetaClass/QMetaProperty though, so I imagine that we don't use Qt reflection system on purpose, for the reasons you just described.

  1. The property system is pretty clunky for access via python
  2. Using introspection rather then a virtual method makes the code less maintainable.

Is it really? I would say it's widely used for good reason 🤷‍♂️

@troopa81
Copy link
Author

I would assume CMYK view without ICC would give a good color match to general printing on coated paper which has a wide color gamut (I mean wide on cmyk scale; such as Fogra39 profile; total ink around 350% I recall).
--> I would suggest that if user has not selected ICC, preview with some "generic" CMYK coated ICC profile such as Fogra39.

Noted, Krita has also a default ICC profile, which would be better than the default "naïve" conversion. I'm gonna amend the QEP to state that QGIS will embed a default ICC profile selected as soon as you select CMYK color space

@nyalldawson
Copy link
Contributor

@troopa81

This is an implementation detail

Agreed 👍 how about dropping these details from the qep and we'll discuss them in depth when it's time to start coding? From a high level perspective this qep looks great and I don't really want to get side tracked on specifics either!

@troopa81
Copy link
Author

Agreed 👍 how about dropping these details from the qep and we'll discuss them in depth when it's time to start coding? From a high level perspective this qep looks great and I don't really want to get side tracked on specifics either!

I'm gonna edit the QEP to state that the color transformation is still to be determined

@tannenfreund87
Copy link

tannenfreund87 commented Mar 4, 2024

CMYK color definition is only meaningfull if it is done respectfully to the color space targeted for printing. If a user wants to work with CMYK colors, he needs to select the ICC profile of the device he plans to print on. This has to be done in the early stage of its project definition, meaning in project properties.

I know this might be out of the scope of this proposal, but can it be implemented with color management in mind? Right now, QGIS like Qt itself is assuming sRGB output. But color industry professionals have AdobeRGB-screens since forever, and the general public is getting more and more P3-display capable screens. It's useless to provide a ICC for the paper output and then just assuming the screen will be sRGB. Also, most "sRBG" screens out there are horribly misconfigured and don't even produce a picture within the range of the sRGB standard.

So, without color management, I propose to ditch the ICC-profiles completely and warn users, that the colors on the screens do not represent the paper output! Without color management one can use the CMYK colors like index colors. You or your printer predefine the colors, you set them as CMYK in QGIS, the screen doesn't match the later output, which is fine, because you'll be softproofing in a color managed application, or your allowed colors for the map have been already set in advance.

Color picker has to be modified to allow selecting a color in CMYK color space. I propose to add a combo box in order for the user to select the color model, either RGB/HSV or CMYK.

Color picker and all gradients in QGIS have suffered under the current implementation. There is always linear blending between the RBG values (128,128,128 is not neutral gray!), but the output is rendered with gamma 2.2. For proper RGB gradients, one would need to perform mixing with linear gamma and convert it to display gamma. Same for the color space. A green, defined in sRGB, might be way to bright on Display-P3 or AdobeRGB.

And CMYK mixing will give completely different gradients, as the color model is fundamentally different!

Implement Color ramp

A CMYK color interpolation algorithm has to be implemented using CMYK components without converting to RGB. A classic linear interpolation will be applied on each component like it is done for RGB interpolation algorithm.

Generating PDF

Print services often requires PDF/X format as input. This PDF format is specially adapted for printing because it enforces some already existing PDF features being mandatory when it comes to printing. Fox example, embedding fonts to be sure that the rendering would be the same for printer for instance.

Qt does not support this format at the moment. It does not allow setting the color profile for the output PDF file neither . These two limitations will have to be removed if we want to be able to print a correct CMYK PDF file.

PDF/X format (when available) will be choosen over default PDF 1.4 version when the user selects a CMYK color model in his project.

Rendering

As described above, when choosing to work in CMYK mode, we target a specific printer for the generated PDF layout/report. In that case, users may want to have an on‑screen preview of how their document’s colors will look, when reproduced on this specific device.

This only works, if the user's screen is exactly adhering to the sRGB-standard. For proper display, you need a calibrated and profiled screen and color management in your app. Or, you do it like in video and film and have a monitor with properly set primaries, then you don't need to profile.

Qt applies a default "naïve" transformation for colors defined in CMYK mode when it comes to draw on an RGB device.

In order to get closer to what the color will actually look like on the printing device, we need to use QColorSpace to load selected ICC profile file, and create a QColorTransform to transform CMYK defined colors from the selected ICC profile to the sRGB color space QColorSpace::SRgb, which Qt operates in by default.

As a consequence, when CMYK mode is enabled, we need to convert all colors before painting.

We could consider develop soft-proofing in order to transform raster RGB working colors to CMYK space and then to screen device, so we can have a better estimation about how raster would look like when printed. This option has been developed in software like Krita or GIMP but I am not not sure that this would be something that QGIS users are interested in. For now, I consider it beyond the scope of this QEP.

This definitely needs color management and a complete overhaul of how colors are internally represented. You need to do all color work internally in a color space big enough to fit at least sRGB and ISO-coated, do all the calculations in linear gamma and convert only the output, on the fly, to display gamma and display color space.

QGIS would need to remove its own, Qt-based painting engine and switch to e.g. krita's, as Qt is not color managed at all and always assuming RGB and sRGB.

Currently, most users don't need color management. Only a fraction of GIS mapmakers actually calibrate and profile their screen. If they produce paper maps, they will likely get printed with desktop printers (I also conflate laser printers and ink plotters of copy shops into that category) and not offset printers. Or the maps will be viewed on uncalibrated and unprofiled computer screens. If your map will end up on a offset printer, you either have the expertise to set the colors or you hopefully have someone else to set it for you. Already being able to set CMYK colors directly would be of great use, as one can define all black lines and text as pure black.

So, I would leave out everything, that only results in a half-hearted attempt on color management. So no ICC-profiles for CMYK unless there is also a way to convert to display gamut and not just sRGB. And think about a solution for color mixing, since without color management, RGB and CMYK will yield visually different results.

@nyalldawson
Copy link
Contributor

@troopa81

I would be in favor of relying less on qt-isms but what exactly is the policy here, because I count more than 300 Q_PROPERTY in QGIS code. It looks like we don't use QMetaClass/QMetaProperty though, so I imagine that we don't use Qt reflection system on purpose, for the reasons you just described.

I realise we're deferring this conversation, but I forgot to answer this bit to fill you in! Q_PROPERTY is only currently used in QGIS code for the sole purpose of exposing things for use in QML (ie by QField/Mergin client), or for custom widgets which are designed to be usable within Qt Designer. That's why there's a lot in master.

@troopa81
Copy link
Author

troopa81 commented Mar 7, 2024

@tannenfreund87 Thank you for your valuable comment. I am not an expert in that particular area so any comment is helpful to provide the best implementation in QGIS.

I know this might be out of the scope of this proposal, but can it be implemented with color management in mind? Right now, QGIS like Qt itself is assuming sRGB output. But color industry professionals have AdobeRGB-screens since forever, and the general public is getting more and more P3-display capable screens. It's useless to provide a ICC for the paper output and then just assuming the screen will be sRGB. Also, most "sRBG" screens out there are horribly misconfigured and don't even produce a picture within the range of the sRGB standard.

For now, I proposed a technical solution which makes only one conversion, from the ICC profile CMYK color space to the sRGB Qt output, but we could apply several transformations and have an extra transformation to the screen colorspace. Do you think it would be enough to implement what you're calling "color management"?

It would require thorough testing to check if it is actually working/relevant.

So, without color management, I propose to ditch the ICC-profiles completely and warn users, that the colors on the screens do not represent the paper output! Without color management one can use the CMYK colors like index colors. You or your printer predefine the colors, you set them as CMYK in QGIS, the screen doesn't match the later output, which is fine, because you'll be softproofing in a color managed application, or your allowed colors for the map have been already set in advance.

I tend to disagree here. Imagine a user creates a QGIS project and sets up its CMYK colors to match a specific printer. Then imagine another user taking over this QGIS project without any communication with the former user. If there is no ICC profile within the project, he has no idea in what color space CMYK colors are described and he has to review all its color to match a new printer/colorspace.

IMHO color space are like projection for coordinates. The later are kind of useless if you don't know in what projection they are used.

PDF/X specification format forces to embed the targeted color space in the PDF file, so I would say that it's relevant to embed it in the QGIS project.

This only works, if the user's screen is exactly adhering to the sRGB-standard. For proper display, you need a calibrated and profiled screen and color management in your app

Anyway, I think you would never have perfect paper rendering on screen, the goal is to get closer as possible, and yes it does require a calibrated screen. Regarding color management in app, see my first comment.

QGIS would need to remove its own, Qt-based painting engine and switch to e.g. krita's, as Qt is not color managed at all and always assuming RGB and sRGB.

Could you elaborate about what Qt is missing to be color managed?

Currently, most users don't need color management. Only a fraction of GIS mapmakers actually calibrate and profile their screen. If they produce paper maps, they will likely get printed with desktop printers (I also conflate laser printers and ink plotters of copy shops into that category) and not offset printers. Or the maps will be viewed on uncalibrated and unprofiled computer screens. If your map will end up on a offset printer, you either have the expertise to set the colors or you hopefully have someone else to set it for you. Already being able to set CMYK colors directly would be of great use, as one can define all black lines and text as pure black.

To be honest, I asked myself this very question from the beginning, What do users actually want ? Like what ArcGIS proposes maybe (and I don't know exactly what's the CMYK color suppport in ArcGIS ?

You mentioned Krita in your comment. QGIS, like this software, can be used to produced output that would be printed using offset printers. And Krita proposes to select the ICC profile and to work regarding this ICC profile. So why not proposing this in QGIS?

And think about a solution for color mixing, since without color management, RGB and CMYK will yield visually different results.

What do you mean by color mixing ? You mean blending a color when painting over another ? When on-screen rendering, it will indeed be done in RGB, not in CMYK color space, so you would not get the color you would get on paper. You would have the issue only if you have transparency but that's a limitation we can live with I think.

@troopa81
Copy link
Author

troopa81 commented Mar 7, 2024

I realise we're deferring this conversation, but I forgot to answer this bit to fill you in! Q_PROPERTY is only currently used in QGIS code for the sole purpose of exposing things for use in QML (ie by QField/Mergin client), or for custom widgets which are designed to be usable within Qt Designer. That's why there's a lot in master.

That makes complete sense. I think using property is not fondamental here and I can avoid duplicate code with helper methods.

@AAnderl
Copy link

AAnderl commented Jun 27, 2024

Great initiative. It would be fantastic if Qgis could be used to generate products for offset printing.
It is important that the program allows the definition of Spot Colors, which are very useful when the design includes very fine lines (for example: coordinate grids or contour lines) and which should be kept out of the color separation, as they could make the registration of four-colour plates too difficult.

@troopa81
Copy link
Author

@AAnderl I don't know much about Spot colors but I'm pretty sure that they are out of the scope of this proposal. From what I understand, that would require to define a way to select them, to encode them correctly into a QGIS project and to properly write them in a PDF export (meaning that it would require probably some Qt development).

design includes very fine lines (for example: coordinate grids or contour lines) and which should be kept out of the color separation, as they could make the registration of four-colour plates too difficult.

No sure to understand what you mean here, could you elaborate?

@AAnderl
Copy link

AAnderl commented Jul 10, 2024

@troopa81 I will try to explain. In the offset printing process, the image to be printed is broken down into the 4 process colors (C, M, Y, K) and a printing plate is made for each of them. The image will be transferred in 4 stages onto the blank paper, and each color is applied on top of the previous one. For the process to be successful, it is essential that each color is applied to the paper in the exact place. When this does not happen, we say there are registration issues.

FalloRegistro

The perfect plate registration does not exist. Fortunately, a minimal deviation goes unnoticed in most cases. Other times, however, a deviation, even if minimal, can be very evident and ruin the entire print. For example, imagine that in my design I include 0.1 mm lines that extend across the entire surface of the design and I do not take the precaution of assigning them a solid color (C, M, Y, or K). In this case, that 0.1 mm line would be broken down into the four plates and would require a very, very precise registration accuracy. This could be the case, for example, with contour lines, and to avoid registration problems, it is common to assign them a Spot color. This color requires an additional plate and, therefore, a fifth printing plate (or an extra color change) in offset printing.

I'm afraid that assigning spot colors is mandatory when it comes to printing maps because it is certain that the design will include grid lines, contour lines, or both. If it were not possible, these lines would have to be assigned one of the process colors, which is a significant limitation.

@frspp
Copy link

frspp commented Jul 10, 2024

It is important that the program allows the definition of Spot Colors, which are very useful when the design includes very fine lines (for example: coordinate grids or contour lines) and which should be kept out of the color separation, as they could make the registration of four-colour plates too difficult.

I'm afraid that assigning spot colors is mandatory when it comes to printing maps because it is certain that the design will include grid lines, contour lines, or both. If it were not possible, these lines would have to be assigned one of the process colors, which is a significant limitation.

Totally disagree - I have never used spot colors in maps. I make everything in RGB/CMYK and at least where I live CMYK registration has always been excellent. I have worked with offset printing presses for past 15 years.

@troopa81
Copy link
Author

@AAnderl Thank you for you detailed informations, I have a better understanding now.

Implementing CMYK in QGIS is a step forward to have a better printing capabilities. Like I said before, Spot color is beyond the scope of this proposal and would require further development (in QGIS and probably Qt). If you are interested in funding or know someone that would be interested, please let me know.

@eurojam
Copy link

eurojam commented Sep 26, 2024

I've just had a look to the new CMYK mode in the color widget and I am wondering about that the CMYK values are between 0 - 255. Normally they should be between 0 - 100 %.

@troopa81
Copy link
Author

@eurojam What version are you using ? CMYK components are in percent in 3.40 see qgis/QGIS#58376

@eurojam
Copy link

eurojam commented Sep 26, 2024

I am just on 3.38.3, but if it comes with 3.40 in percent that would be great. I am aware that PDF export does not keep the CMYK colors so far, I suppose this will come with Qt6 in the near future. May be we can fund the upcoming features with CMYK support, depending on the decission of the company head...I will ask them...

@troopa81
Copy link
Author

I am aware that PDF export does not keep the CMYK colors so far, I suppose this will come with Qt6 in the near future.

This has been already done, by KDAB for the Qt part and myself (Oslandia) for the QGIS part. And yes, the PDF export works only in Qt 6 (because QT 6 is EOL so all new features land in Qt 6), but you can test it using QGIS Qt 6 unofficial version OSGeo4W (qgis-qt6-dev version).

@troopa81
Copy link
Author

troopa81 commented Oct 1, 2024

Development has been completed and is available in QGIS 3.40 Qt 6.

The rendering part, allowing users to have an on‑screen preview of how their document’s colors will look when reproduced on a specific device has not been implemented because I don't think there is a great user need. If you think otherwise, and/or willing to fund this part, please let me know.

Until then, I close the issue.

@troopa81 troopa81 closed this as completed Oct 1, 2024
@eurojam
Copy link

eurojam commented Oct 1, 2024 via email

@troopa81
Copy link
Author

troopa81 commented Oct 2, 2024

Hi Stefan,

Actually we are still depending on Qt 6.6 and so we don't ship last Kdab development in 6.8. My mistake, I believed we were already on Qt 6.8.

Qt 6.8 was expected for september 2024 so it should be released soon. Then, we would have to update our packaging. I don't know how long it takes, and I don't know if we have special policy on potential minimal Qt patch version we are relying on (I see we are currently on 6.6.3, could we imagine be on 6.8.0 @jef-n when its out ? )

That explains your issues.

Regarding the remaining part requiring funding, I'll answer you by mail.

@troopa81
Copy link
Author

troopa81 commented Oct 3, 2024

Qt 6.8 was expected for september 2024 so it should be released soon. Then, we would have to update our packaging.

We also would have to wait for PyQt 6.8, so a little more delay...

@jsehner
Copy link

jsehner commented Nov 13, 2024

Strongly appreciate this development and very detailed documentation! A question to the timeline: In QGIS 3.40 the CMYK-Export doesn't work yet. In the chapter limitations the complete support for CMYK is estimated with QGIS 4.XX. When will that be? The roadmap ends in January 2026 with v3.46. So no official support in 2025?

@andreasneumann
Copy link
Member

@jsehner - CMYK is already available in QGIS 3.40 - however, only if QGIS was built against Qt 6. Our standard builds are still built against Qt5, because a switch to Qt6 would break most Python plugins.

In short: if you want CMYK support in QGIS, please install (in parallel) a Qt6 version. The OSGeo4W installer contains both the Qt5 and the Qt6 versions: Select the qgis-qt6-dev versions

It might be a while until we enable Qt6 for the standard version because of the Python compatibility issues mentioned above ... so until then, please use the "qgis-qt5-dev" version - which can be installed and run in parallel with the Qt5 versions.

@troopa81
Copy link
Author

In short: if you want CMYK support in QGIS, please install (in parallel) a Qt6 version. The OSGeo4W installer contains both the Qt5 and the Qt6 versions: Select the qgis-qt6-dev versions

Not only qt6, but Qt 6.8 like I described here.

I'm actually working on building a QGIS CMYK Qt 6.8 preview version. I hope it would be avaiable for testing next week

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants