microsoft / PowerToys

Windows system utilities to maximize productivity
MIT License
111.44k stars 6.56k forks source link

[ColorPicker] Current Naive CMYK conversion function is not useful (or accurate) #17036

Open m13253 opened 2 years ago

m13253 commented 2 years ago

Description of the new feature / enhancement

Currently, ColorPicker uses Naive CMYK conversion function to convert sRGB to CMYK.

black = 1 - max(red, green, blue)
cyan = (1 - red - black) / (1 - black)
magenta = (1 - green - black) / (1 - black)
yellow = (1 - blue - black) / (1 - black)

This conversion function was coincidentally also defined in CSS Color Model Level 4 (old draft version 2021-06-01), [1] but Naive CMYK was removed in the latest draft version 2021-12-15 [2], probably due to being useless.

As far as I know, no other popular software uses this conversion function.

Why Naive CMYK is not useful (also not accurate)?

  1. When multiple inks are printed on paper, some chemical and physical reactions happen. It is difficult to predict with math only.
  2. The tone responsive of ink does not follow simple gamma rule, and the hue may even slightly change given single ink at different density.
  3. One color may have multiple representations in CMYK. There is something called “black generation curve” that defines which representation to prefer. [3] A typical black generation curve uses more CMY than K for light to medium gray, and uses more K than CMY for dark gray and black. This is to reduce banding effect and halo effect.

Which CMYK color spaces are useful?

In practical, a graphics designer who needs to use CMYK will need to deal with two CMYK color spaces:

  1. A “working color space”, a standardized color space that the designing software uses to store images. Typical examples are:
    • FOGRA39 CMYK (ISO Standard, also recommended by W3C Color Model Level 4.)
    • SWOP v2 CMYK (American standard, also default for Adobe Photoshop.)
    • Apple Generic CMYK (Default for macOS, nobody else uses it, but easier to compute.)
    • PostScript DeviceCMYK (PostScript Language Reference Manual §7.2.3 [4]) (Default for LaTeX, mistakenly. It's called “Device”CMYK for a reason, so don't use it.)
  2. A “device color space”, which depends on specific printer, paper, and ink. Graphics designing software uses either ICC DeviceLink or Profile Connecting Space (PCS) to convert into them. Therefore, we don't need to care about device color spaces.

Therefore, the solution is to target one (or multiple) standardized working color space.

What is the solution?

Unfortunately, there is no analytical formula to do the conversion, due to the reason I described. The fastest way is to use a Look-up Table (LUT).

There are 4 options, choose either one of below:

  1. Call the color management API provided by Windows. (ICC files are available at [5] and [6], copyright allows redistribution but not modification)
  2. Or, import open-source library: LittleCMS2 is used by GIMP and other popular software.
  3. Or, do the LUT lookup on our own. (Data are available at [7] and [8], be aware of copyright)
  4. Or, precompute all 16,777,216 sRGB colors, so we don't need to embed a color management engine.
  5. Or, just give up and remove CMYK from PowerToys. It's better not having this feature altogether, rather than misleading the users.

Scenario when this would be used?

The (only) scenario that (I can think of) is:

  1. When the user sees a color that they want to pick, either from a document or a web page.
  2. The user picks the color, copies the CMYK values.
  3. The user types the CMYK values to a designing software, e.g., Adobe Photoshop or Affinity Designer.

Therefore, it is important that the CMYK value produced by ColorPicker is in a standarized “working color space”, as introduced in above section.

There is no reason that a user would ever need Naive CMYK.

Supporting information

References

  1. W3C. CSS Color Model Level 4 (old draft version 2021-06-01): https://www.w3.org/TR/2021/WD-css-color-4-20210601/
  2. W3C. CSS Color Model Level 4 (new draft version 2021-12-15): https://www.w3.org/TR/2021/WD-css-color-4-20211215/
  3. ArgyllCMS. Typical usage scenarios: https://www.argyllcms.com/doc/Scenarios.html
  4. Adobe. PostScript Language Reference Manual: https://www.adobe.com/jp/print/postscript/pdfs/PLRM.pdf
  5. ICC. ICC Profile Registry: https://www.color.org/registry/index.xalter
  6. Adobe. Adobe ICC Profiles download for Windows: https://www.adobe.com/support/downloads/iccprofiles/iccprofiles_win.html
  7. ICC. CMYK Characterization Data: https://www.color.org/chardata/drsection1.xalter
  8. FOGRA. Characterisation Data: https://fogra.org/en/downloads/work-tools/characterisation-data

Test colors

ICC profile used: Adobe ICC profile bundle, macOS ColorSync built-in profiles. Rendering intent: relative colorimetric. Black point compensation: enable.

sRGB FOGRA39 CMYK SWOP v2 CMYK Apple Generic CMYK Naive CMYK
#9E6678 34%, 63%, 34%, 16% 37%, 67%, 38%, 7% 33%, 63%, 31%, 4% 0%, 35%, 24%, 38%
#3F8376 75%, 29%, 55%, 13% 76%, 31%, 57%, 9% 75%, 25%, 50%, 9% 52%, 0%, 10%, 49%
#82764C 43%, 40%, 71%, 28% 45%, 44%, 77%, 18% 40%, 40%, 75%, 15% 0%, 9%, 42%, 49%
#6378A1 67%, 49%, 20%, 4% 67%, 51%, 19%, 1% 63%, 45%, 10%, 1% 39%, 25%, 0%, 37%
#777777 51%, 42%, 41%, 25% 54%, 47%, 46%, 11% 55%, 47%, 43%, 3% 0%, 0%, 0%, 53%
#000000 89%, 78%, 62%, 97% 72%, 68%, 67%, 88% 74%, 71%, 65%, 80% 0%, 0%, 0%, 100%

There might be less than 1% round-off error in my provided data. Although CSS Color Model Level 4 draft proposes using ceil(), Affinity Designer, LittleCMS2, as well as my values here use round().

TheJoeFin commented 1 year ago

This is a very technical issue, and needs to be addressed. Changes have been made to color picker since this issue was opened. Can you confirm this issue is still relevant in v0.73? /needinfo

m13253 commented 1 year ago

I believe it is still relevant. Naïve CMYK values are not used in any graphical application, thus not useful.

I would recommend either (1) including a color management framework or call the operating system’s provided API to do the conversion using an ICC file, (2) just remove the CMYK values to prevent misleading people.