# How do I get K with CMY Function?

When I have a Color, I know how to extract its amount of Cyan, Magenta and Yellow, but now I want to get its Black.

How do I achieve that ?

A Google quest returned answers about printing in CMYK, nothing about extracting K from the color value.

You donâ€™t.

First of all, for anyone that doesnâ€™t know, weâ€™re talking about:
C Cyan
M Magenta
Y Yellow
K BlacK

These are the colors that are used for reproducing color on a printed page, as opposed to RGB for screens.

The Xojo properties are just inversions of one anotherâ€¦

C = 255 - R
M = 255 - G
Y = 255 - B

If youâ€™ve ever mixed paints, youâ€™ll remember that you canâ€™t actually get black by mixing these together. You get more of a dark brown. Black ink is used to replace a portion of the places where all three are meant to be black.

If youâ€™re still curious, read onâ€¦

The black (K) portion is difficult to quantify because how itâ€™s calculated is dependent on the type of paper that you are printing on.

Paper is porous. That is, when a drop of ink is placed on it, the ink tends to bleed a bit. How much it bleeds is directly related to the amount of black ink thatâ€™s used. Think of the difference between the paper thatâ€™s used in a greeting card vs whatâ€™s used in a telephone book (if you remember those). Try dropping a bead of water on each of these and youâ€™ll see what I mean.

Now, when color ink is applied to paper to make colors, they are overlaid onto the page. The problem that arises is that because colors bleed, the more ink thatâ€™s applied to the page in a particular spot, the muddier the image gets. If you tried to apply 10% of CMY youâ€™d be fine, but 100% not so much because the paper can only absorb so much ink. Black is used to substitute a certain portion of these solid ink areas to avoid this problem.

But hereâ€™s the rubâ€¦ the amount of color replacement varies based on the % of color thatâ€™s on the paper as well. So you canâ€™t just assume that youâ€™ll be replacing straight values either:

C 10
M 70
Y 30

C 0
M 60
Y 20
K 10

The way the black replacement of color is done is based on algorithms of how we perceive color.

TL;DR: If you want to do this accurately, youâ€™re going to need to get into Color Profiles which is a whole other discussion, and not something thatâ€™s particularly easy to implement in Xojo. People have done it, itâ€™s just not easy.

2 Likes

Thank you Greg for your explanation.

Hereâ€™s what I was doing (no more):

Black (CMYK) is wrong and so is HSV on this working screen shot.

On the left are the names, hex values and color from the HTML definitions; and on the right, I displayed more information about the ListBox selected color.

In relation to what though? Since thereâ€™s no way to get that value in Xojo, you must be doing some sort of calculation there. (Although it looks close to right)

I sort the Hex value Column; then select the first one, look at the black Canvas (from CMYK) and press the bottom arrow key until the 148Â° Row: the Black rendered color does not change very muchâ€¦

I add C+M+Y values and / the result by 3â€¦ to set a value for Black (itâ€™s an idea like any other). That value change (of course).

Yesterday evening, I checked with TextEdit Color windoid, CMYK and moved the K value: no change in each of the three C, M & Y values (of course).
Edit: I just checked, and the amount of K changes. I do not say it have a correct value, but both the computed value and the rendered Black change (depending on the selected color in the ListBox.

I have to think at what I will do with this project. (Remove K and share it ?)

Perhaps you may find what you need in an open source color management engine like the LITTLE CMS OPEN SOURCE COLOR ENGINE.

Since CMYK is a device specific color space probably the best general CMYK color profile to use is the Idealliance GRACOL G7 ICC Profile which has become a standard for the print industry. If the RGB colors you are using are Web colors then the SRGB Profile would be the one to use for profile to profile conversion.

1 Like

In my experience, there are no systems that do this. Black is added to a color while parts of CYAN, Magenta and Yellow are removed, but they are not equal parts because black tends to be a cool color all on its own.

If you want to do this â€ścorrectly,â€ť youâ€™re going to have to use declares.

My point is, donâ€™t guess. The people who work with CMYK will immediately realize that your app is broken.

You can use MBS Plugins to convert. We have classes for this and here is some example code

``````dim ct as LCMS2TransformMBS
dim mi,mo as MemoryBlock
dim pi as LCMS2ProfileMBS
dim po as LCMS2ProfileMBS
dim f as FolderItem

// you find this profiles on Mac OS X in /System/Library/ColorSync/Profiles
f = FindFile("Generic RGB Profile.icc")
pi = LCMS2ProfileMBS.OpenProfileFromFile(F)

if pi = nil then
MsgBox "Failed to find the profile."+EndOfLine+EndOfLine+f.Name
end if

f = FindFile("Generic CMYK Profile.icc")
po = LCMS2ProfileMBS.OpenProfileFromFile(F)

if po = nil then
MsgBox "Failed to find the profile."+EndOfLine+EndOfLine+f.Name
end if

// get data format for 8 bit integers
dim pif as integer = pi.FormatterForColorspace(1, false)
dim pof as integer = po.FormatterForColorspace(1, false)

dim flags as integer = LCMS2MBS.kcmsFLAGS_BLACKPOINTCOMPENSATION

ct = LCMS2TransformMBS.CreateTransform(pi, pif, po, pof, intent, flags)

canvas1.Backdrop = NewColorPicture(c)

' ... fill c
mi=NewMemoryBlock(3) // RGB
mo=NewMemoryBlock(4) // CMYK

mi.UInt8Value(0)=c.red
mi.UInt8Value(1)=c.green
mi.UInt8Value(2)=c.blue

if ct.Transform(mi,mo,1) then
'ok

dim cc as integer = mo.UInt8Value(0) // C
dim mm as integer = mo.UInt8Value(1) // M
dim yy as integer = mo.UInt8Value(2) // Y
dim kk as integer = mo.UInt8Value(3) // K

// convert back
ct = LCMS2TransformMBS.CreateTransform(po, pof, pi, pif, intent)

if ct.Transform(mo,mi,1) then
dim rr as integer = mi.UInt8Value(0) // R
dim gg as integer = mi.UInt8Value(1) // G
dim bb as integer = mi.UInt8Value(2) // B

info.text = str(c.red)+" "+str(c.Green)+" "+str(c.Blue)+EndOfLine+_
str(cc)+" "+str(mm)+" "+str(yy)+" "+str(kk)+EndOfLine+_
str(rr)+" "+str(gg)+" "+str(bb)+EndOfLine

canvas2.Backdrop = NewColorPicture(rgb(rr,gg,bb))

end if

end if
``````

## RGB to CMYK conversion formula

The R,G,B values are divided by 255 to change the range from 0â€¦255 to 0â€¦1:

Râ€™ = R/255

Gâ€™ = G/255

Bâ€™ = B/255

The black key (K) color is calculated from the red (Râ€™), green (Gâ€™) and blue (Bâ€™) colors:

K = 1-max(Râ€™, Gâ€™, Bâ€™)

The cyan color (C) is calculated from the red (Râ€™) and black (K) colors:

C = (1-Râ€™-K) / (1-K)

The magenta color (M) is calculated from the green (Gâ€™) and black (K) colors:

M = (1-Gâ€™-K) / (1-K)

The yellow color (Y) is calculated from the blue (Bâ€™) and black (K) colors:

Y = (1-Bâ€™-K) / (1-K)

Yes, but that simple formula is usually wrong as you need proper color profiles to describe what your RGB is and what CMYK should be.

That formula is very useful if you are not concerned about ink-soaked paper or accurate color reproduction.

If you donâ€™t care about accurate colour reproduction why bother with CMYK at all?

3 Likes

Well. The formula you listed above is incorrect. With the correct formula there would not be anything wrong the conversations. If conversion calculations in general are the correct way of converting color from a math perspective. Itâ€™s just without a proper color profile for a particular output method, for a given printer or ink/paper or display, the colors will just be perceived differently. so rgb(0,23,26) without a profile versus rgb(0,23,26) with an SRGB profile with still be the same values but display differently. So it might look different but the values making a math conversion from rgb would be cmyk is correct. Especially since CMYK contains less colors than RGB.

FYI. Find a better rgb to CMYK formula.