如何在Python中将RGB转换为CMYK,以及反之?

18
如果我有一个RGB十进制值,例如255, 165, 0,我应该怎么转换成CMYK?
例如:
>>> red, green, blue = 255, 165, 0
>>> rgb_to_cmyk(red, green, blue)
(0, 35, 100, 0)
7个回答

26

这是一个Python版本的Javascript实现

RGB_SCALE = 255
CMYK_SCALE = 100


def rgb_to_cmyk(r, g, b):
    if (r, g, b) == (0, 0, 0):
        # black
        return 0, 0, 0, CMYK_SCALE

    # rgb [0,255] -> cmy [0,1]
    c = 1 - r / RGB_SCALE
    m = 1 - g / RGB_SCALE
    y = 1 - b / RGB_SCALE

    # extract out k [0, 1]
    min_cmy = min(c, m, y)
    c = (c - min_cmy) / (1 - min_cmy)
    m = (m - min_cmy) / (1 - min_cmy)
    y = (y - min_cmy) / (1 - min_cmy)
    k = min_cmy

    # rescale to the range [0,CMYK_SCALE]
    return c * CMYK_SCALE, m * CMYK_SCALE, y * CMYK_SCALE, k * CMYK_SCALE

错误:[min_cmy = min(c, m, y)]正确:[min_cmy = min(c, m, y)] - Denis Barmenkov
没有一个初始条件,这个函数就没有多大意义。 - jedierikb

14

接受的答案提供了一种很好的从RGB到CMYK的方法,但问题标题也包括

反之亦然

因此,这是我为从CMYK转换为RGB所做出的贡献:

def cmyk_to_rgb(c, m, y, k, cmyk_scale, rgb_scale=255):
    r = rgb_scale * (1.0 - c / float(cmyk_scale)) * (1.0 - k / float(cmyk_scale))
    g = rgb_scale * (1.0 - m / float(cmyk_scale)) * (1.0 - k / float(cmyk_scale))
    b = rgb_scale * (1.0 - y / float(cmyk_scale)) * (1.0 - k / float(cmyk_scale))
    return r, g, b

与patapouf_ai的答案不同,这个函数不会导致RGB值为负。


11

但将完整图像从RGB转换为CMYK或相反方向的转换非常简单:

from PIL import Image
image = Image.open(path_to_image)

if image.mode == 'CMYK':
    rgb_image = image.convert('RGB')

if image.mode == 'RGB':
    cmyk_image = image.convert('CMYK')

8

继Fooz先生的实现之后。

CMYK有两种可能的实现方式。一种是相对于白色空间的比例(例如在GIMP中使用),这也是Fooz先生实现的方式,但另一种是相对于整个色彩空间的颜色比例(例如在LibreOffice中使用)。如果您希望使用CMYK来模拟颜料或油墨混合,则第二种方法可能更好,因为可以使用每种颜色的权重将颜色线性地添加在一起(半半混合使用0.5的权重)。

以下是带有反向转换的第二个版本的CMYK:

rgb_scale = 255
cmyk_scale = 100


def rgb_to_cmyk(r,g,b):
    if (r == 0) and (g == 0) and (b == 0):
        # black
        return 0, 0, 0, cmyk_scale

    # rgb [0,255] -> cmy [0,1]
    c = 1 - r / float(rgb_scale)
    m = 1 - g / float(rgb_scale)
    y = 1 - b / float(rgb_scale)

    # extract out k [0,1]
    min_cmy = min(c, m, y)
    c = (c - min_cmy) 
    m = (m - min_cmy) 
    y = (y - min_cmy) 
    k = min_cmy

    # rescale to the range [0,cmyk_scale]
    return c*cmyk_scale, m*cmyk_scale, y*cmyk_scale, k*cmyk_scale

def cmyk_to_rgb(c,m,y,k):
    """
    """
    r = rgb_scale*(1.0-(c+k)/float(cmyk_scale))
    g = rgb_scale*(1.0-(m+k)/float(cmyk_scale))
    b = rgb_scale*(1.0-(y+k)/float(cmyk_scale))
    return r,g,b

cmyk_to_rgb的结果是负数,例如c=100,m=100,y=100,k=100 => r=-255,g=-255,b=-255。其次,为什么你需要self呢? - gkcn
@gkcn 谢谢,确实不应该有一个"self"(在我的代码中它在一个类中,那里有一个self,我只是忘记在复制粘贴时将其删除)。 - patapouf_ai
@gkcn c=100,m=100,y=100,k=100 不是有效的CMYK值,这就是为什么。 - patapouf_ai

5
使用像接受答案中给出的CMYK转换方式(截至本篇撰写时)对于大多数实际目的来说是不准确的。 CMYK基于四种油墨在纸张上形成颜色的方式;然而,油墨的混合色彩相当复杂,比RGB颜色模型中用于形成颜色的“光”混合更加复杂。 由于CMYK主要用于打印图像,因此任何转换为CMYK的操作都需要考虑到打印条件,包括所用的打印机和纸张。 准确地将图像转换为CMYK以进行打印并不是一件简单的事情,它需要校准打印机并测量测试版上的CMYK块等其他操作。 对于CMYK颜色,没有像sRGB对RGB那样普遍存在的含义,这一点在国际色彩联盟的CMYK表征数据页面中有所体现。

此外,关于这个主题,还可以参见我的颜色文章


2

1
我尝试使用bisounours_tronconneuse提供的反向计算方法,但对于CMYK(96 63 0 12)失败了。结果应该是:像这样 将w3schools的javascript代码(此处代码)转换为Python后,下面的代码现在返回正确的结果:
def cmykToRgb(c, m, y, k) :
    c=float(c)/100.0
    m=float(m)/100.0
    y=float(y)/100.0
    k=float(k)/100.0
    r = round(255.0 - ((min(1.0, c * (1.0 - k) + k)) * 255.0))
    g = round(255.0 - ((min(1.0, m * (1.0 - k) + k)) * 255.0))
    b = round(255.0 - ((min(1.0, y * (1.0 - k) + k)) * 255.0))
    return (r,g,b)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接