Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMY colour function in R

Tags:

r

Is there a CMY colour function in any R package equivalent to rgb()? There seems to be nothing in {base} or e.g. {colourSpace}. I have a custom function which I can post here, but a native would be preferable.

like image 389
geotheory Avatar asked Mar 12 '14 13:03

geotheory


People also ask

Is CMY and CMYK the same?

The CMYK color space is a variation on the CMY model. It adds black (Cyan, Magenta, Yellow, and blacK). The CMYK color space closes the gap between theory and practice. In theory, the extra black component is not needed.

Why is CMY better than RGB?

Fundamentally, RGB is best for websites and digital communications, while CMYK is better for print materials. Most design fields recognize RGB as the primary colors, while CMYK is a subtractive model of color. Understanding the RGB and CMYK difference is an essential part of successful graphic design.

Why is CMYK not CMY?

The reason printing uses CMYK comes down to an explanation of the colors themselves. CMY will cover most lighter color ranges quite easily, compared to using RGB. However, CMY by itself can't create very deep dark colors like “true black,” so black (designated “K” for “key color”) is added.


3 Answers

this should work

#' assumes integer input for CMYK
cmyk <- function(C,M,Y,K) {

  C <- C / 100.0
  M <- M / 100.0
  Y <- Y / 100.0
  K <- K / 100.0

  n.c <- (C * (1-K) + K)
  n.m <- (M * (1-K) + K)  
  n.y <- (Y * (1-K) + K)

  r.col <- ceiling(255 * (1-n.c))
  g.col <- ceiling(255 * (1-n.m))
  b.col <- ceiling(255 * (1-n.y))

  return(col2rgb(sprintf("#%02s%02s%02s",
                     as.hexmode(r.col), 
                     as.hexmode(g.col), 
                     as.hexmode(b.col))))

}

> cmyk(0,50,85,0)
      [,1]
red    255
green  128
blue    39

> cmyk(0,0,100,0)
      [,1]
red    255
green  255
blue     0
like image 53
hrbrmstr Avatar answered Oct 19 '22 05:10

hrbrmstr


Well in addition to @hrbrmstr's function here is mine for what its worth. I haven't factored in black as I understand that's primarily for printing but I'd see this primarily as a dataviz tool. It should work with vectors / matrices / alphas.

cmy = function(c, m, y, alpha, maxColorValue=1){
  if(maxColorValue != 1) { c <- c/maxColorValue; m <- m/maxColorValue; y <- y/maxColorValue }
  c <- 1-c; m <- 1-m; y <- 1-y
  hex <- function(v) substring(rgb(v,0,0),2,3)
  if(!missing(alpha)) alpha <- hex(alpha) else alpha <- ''
  paste0('#',hex(c), hex(m), hex(y), alpha)
}
like image 24
geotheory Avatar answered Oct 19 '22 05:10

geotheory


If you're into code porting, I found a couple MatLab Central possibilities:

http://www.mathworks.com/matlabcentral/fileexchange/25350-fit-multi-dimensional-polynomial (despite the name, the description says 'CMYK to Lab'

http://www.mathworks.com/matlabcentral/fileexchange/45723-convert-rgb-image-to-cmy-image-and-extract-each-component-cyan-c-magenta-m-and-yellow-y

EDIT: if you'd like to invert hrbmstr's code, here's some javascript which can trivially be converted to R Courtesy of http://www.javascripter.net/faq/rgb2cmyk.htm ):

 if (r==0 && g==0 && b==0) {
  computedK = 1;
  return [0,0,0,1];
 }

 computedC = 1 - (r/255);
 computedM = 1 - (g/255);
 computedY = 1 - (b/255);

 var minCMY = Math.min(computedC,
              Math.min(computedM,computedY));
 computedC = (computedC - minCMY) / (1 - minCMY) ;
 computedM = (computedM - minCMY) / (1 - minCMY) ;
 computedY = (computedY - minCMY) / (1 - minCMY) ;
 computedK = minCMY;
like image 23
Carl Witthoft Avatar answered Oct 19 '22 05:10

Carl Witthoft