【问题标题】:Adding Colours (Colors) Together like Paint (Blue + Yellow = Green, etc)像油漆一样添加颜色(颜色)(蓝色+黄色=绿色等)
【发布时间】:2012-04-25 18:12:36
【问题描述】:

我正在使用 cocos2d 库制作 iOS 游戏。

假设您有两个具有两种不同颜色的对象 - 在 RGB 中定义为

Blue:    0,0,255
Yellow:  255,255,0

我想加蓝色和黄色变成绿色。

为了让事情变得过于复杂,假设蓝色对象比黄色对象大(为了论证,假设比例是 2:1),我添加的蓝色是黄色的两倍 - 如何我正确计算了这个新的(浅绿色)颜色。

我了解 LAB * 颜色空间对于这种“自然颜色”类型的东西很有用,但我不确定如何使用它——尤其是在 cocos2d 对象的上下文中(AFAIK)仅限使用RGB 的配色方案。

非常感谢有关如何实现此功能的实际帮助。多谢!

21/4 更新:所以在 LAB* 中,蓝色+黄色 ≠ 绿色(当您看到 they're at opposite ends of the same channel 时这是有道理的)。对于 SO 的讨论,littlebit 实际上是一个相当棘手的问题。似乎最终的答案是使用一个名为 Krita 的开源软件使用的 Kubelka-Munk 方法。我在任何地方都找不到(公式或代码本身)。

This questiona link,它使用 HSL 以类似的方法进行绘画。我会尝试看看它是否有效,我会在这里反馈结果。

与此同时,if anyone knows how to implement Kubelka-Munk 或者我可以在哪里找到执行此操作的代码或其他解决方案,我会非常非常激动!

【问题讨论】:

  • Blue + Yellow 永远不会是 Green,尽管你在学前班就知道了。这实际上指的是一个简单的减色模型,例如 CMYK,其中1 - Cyan - Yellow ≈ Green(与Cyan ≈ Blue)。

标签: c++ objective-c math colors cocos2d-iphone


【解决方案1】:

查看本网站上的公式:http://www.easyrgb.com/index.php?X=MATH 我一直在做类似的事情,可以通过转换RGB->XYZ->Lab来实现。然而计算是相当昂贵的(如果你做很多像素)。

如果你想获得类似于人眼的结果,在尝试混合颜色时忘记 RGB 数学

【讨论】:

  • 所以 objectA、objectB 用 RGB 着色 - 将 RGB 转换为 XYZ,然后转换为 LAB,将两种颜色相加,然后再将它们转换回 XYZ 和 RGB?
  • 是的,正如我写的那样,它需要大量计算(我逐像素分析了整个图像)但给出了不错的结果
  • 当您在 LAB 空间中将两种颜色相加时。这是如何正确完成的?只是 L1*0.5 + L2*0.5、A1*0.5 + A2*0.5 和 B1*0.5 + B2*0.5?
【解决方案2】:

我认为,值得尝试 HSL 色彩空间。添加颜色时,我们会插入它们的色调值(甚至考虑到对象的权重)。如果颜色为 100% 饱和度,则亮度和饱和度值将相等。

【讨论】:

    【解决方案3】:

    没有将蓝色和黄色混合成绿色的颜色模型。自己试试水粉画,唯一有效的方法是青色和黄色。这就是为什么您应该尝试从 RGB 切换到 CMYK,并在需要时返回。这是它的完成方式

    void toCMYK(float red, float green, float blue, float* cmyk)
    {
      float k = MIN(255-red,MIN(255-green,255-blue));
      float c = 255*(255-red-k)/(255-k); 
      float m = 255*(255-green-k)/(255-k); 
      float y = 255*(255-blue-k)/(255-k); 
    
      cmyk[0] = c;
      cmyk[1] = m;
      cmyk[2] = y;
      cmyk[3] = k;
    }
    
    void toRGB(float c, float m, float y, float k, float *rgb)
    {
      rgb[0] = -((c * (255-k)) / 255 + k - 255);
      rgb[1] = -((m * (255-k)) / 255 + k - 255);
      rgb[2] = -((y * (255-k)) / 255 + k - 255);
    }
    

    然后在你的代码中,混合青色和黄色

    float cmyk1[4];
    toCMYK(255, 255, 0, cmyk1);  // yellow
    
    float cmyk2[4];
    toCMYK(0, 255, 255, cmyk2);  // cyan
    
    // Mixing colors is as simple as adding
    float cmykMix[] = { cmyk1[0] + cmyk2[0], cmyk1[1] + cmyk2[1], cmyk1[2] + cmyk2[2], cmyk1[3] + cmyk2[3] };
    
    float rgb[3];
    toRGB(cmykMix[0], cmykMix[1], cmykMix[2], cmykMix[3], rgb);  
    
    NSLog(@"RGB mix = (%f, %f, %f)", rgb[0], rgb[1], rgb[2]);
    

    运行代码将产生:RGB mix = (0.000000, 255.000000, 0.000000)

    【讨论】:

    • 非常感谢您的回答,尤其是代码。我认为这适用于黄色加蓝色 - 但我不知道它是否适用于其他颜色算术。我一直在对此进行一些研究,并得到这样的答案:stackoverflow.com/a/398268/459116 让它看起来像 LAB 是最好的方法。
    • 我用黄色和蓝色的模型涂料完成了它,蓝色是深蓝色,不是“绿色”——绝对不是“青色”,结果肯定是绿色。这种事情不会发生在印花染料上,但很容易发生在油漆上,有时也会发生在染料上。 (有关更多信息,请参阅我的答案)
    【解决方案4】:

    染料在现实世界中并不像减色模型所暗示的那样有效。用于 CYMK 印刷的染料非常接近,因为它们是为此目的而配制的,但许多由天然物质制成的染料可能表现得有些奇怪。困难在于,虽然白光被认为是红色、绿色和蓝色的组合,但它实际上由许多不同的波长组成——字面意思是“彩虹的所有颜色”——每一种都会刺激红色、绿色、和眼睛中不同数量的蓝色受体。两种看起来相同的颜色实际上可能包含不同的波长组合;同样,两种染料在白光下可能看起来相同,但吸收不同的波长组合。这些染料单独使用时可能看起来彼此相同,但与其他染料结合使用时可能会产生截然不同的结果。

    虽然染料有时会很棘手,但油漆更糟糕。油漆含有反射粒子,一些照射到油漆表面的光会被它击中的第一个粒子反射回表面;在这方面,它们像加色一样混合。例如,如果油漆含有 20% 的绿色颗粒,那么无论它可能包含什么其他颜色,都会反射大量的绿光。另一方面,一些照射到涂漆表面的光会反弹并击中多个粒子。如果这些粒子中的任何一个吸收了某种颜色的光子,则该光子将不会被反射。在这方面,油漆的行为更像是减色。在实践中,颜料的行为有点像加色,有点像减色,有时又像一些奇怪而古怪的东西,完全不同。

    【讨论】:

      【解决方案5】:

      实际上,转换 RGB->XYZ->LAB 似乎与 RGB->LAB 完全一样

      【讨论】:

        猜你喜欢
        • 2012-05-02
        • 2020-06-10
        • 2011-10-28
        • 2014-02-23
        • 2011-05-08
        • 1970-01-01
        • 2021-07-07
        • 2012-06-27
        • 2013-12-19
        相关资源
        最近更新 更多