求助:如何计算两种色光混合后的R、G、B值?

wangtong2010 2015-05-25 12:51:23
第一种色光的颜色值为r1,g1,b1,第二种色光的颜色为r2,g2,b2,那么两种混合后的颜色RGB各是多少?有效取值范围为0到255。
...全文
1396 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
xlcsfa 2016-08-09
  • 打赏
  • 举报
回复
xuzuning,你的算法似乎有问题
失落的神庙 2015-05-28
  • 打赏
  • 举报
回复
引用 26 楼 xuzuning 的回复:
xuzuning 2015-05-28
  • 打赏
  • 举报
回复
应该用 HSB 计算混色结果
不过学艺不精,把握不好度。献丑了

下面文本框列分别是 左色、混合色、右色
左边从上往下依次是 左色、混合色、右色 的 HSB 值
混合色采用了 Photoshop 的 Screen 滤色 混合模式:C=1-(1-A)*(1-B)
右边是 左色 + 右色 的 HSB 和 RGB 值 和例图

由于是 vs2010 写的项目,这里又不能发附件。所以只贴出我的 HSB 类(两个功能:重载 + 运算符、HSB 到 RGB 的转换)
class HSB
{
public float H; //色调
public float S; //饱和度
public float B; //亮度

public HSB()
{
H = 0;
S = 1;
B = 1;
}
public HSB(HSB hsb)
{
H = hsb.H;
S = hsb.S;
B = hsb.B;
}
public HSB(Color color)
{
H = color.GetHue();
S = color.GetSaturation();
B = color.GetBrightness();
}
public override string ToString()
{
return "H:" + H + " S:" + S + " B:" + B;
}
public static HSB operator +(HSB lhs, HSB rhs)
{
HSB result = new HSB(lhs);
var h1 = result.H;
var h2 = rhs.H;
if (rhs.H - h1 > 180) h1 += 360f;
result.H = (rhs.H - h1) / 2 + h1;
if (result.H == 360f) result.H = 0f;

result.S = rhs.S;
result.B = rhs.B * 2;

return result;
}
public Color ToColor()
{
double r = 0;
double g = 0;
double b = 0;

if (S == 0)
{
r = g = b = B;
}
else
{
// the color wheel consists of 6 sectors. Figure out which sector you're in.
double sectorPos = H / 60.0;
int sectorNumber = (int)(Math.Floor(sectorPos));
// get the fractional part of the sector
double fractionalSector = sectorPos - sectorNumber;

// calculate values for the three axes of the color.
double p = B * (1.0 - S);
double q = B * (1.0 - (S * fractionalSector));
double t = B * (1.0 - (S * (1 - fractionalSector)));

// assign the fractional colors to r, g, and b based on the sector the angle is in.
switch (sectorNumber)
{
case 0:
r = B;
g = t;
b = p;
break;
case 1:
r = q;
g = B;
b = p;
break;
case 2:
r = p;
g = B;
b = t;
break;
case 3:
r = p;
g = q;
b = B;
break;
case 4:
r = t;
g = p;
b = B;
break;
case 5:
r = B;
g = p;
b = q;
break;
}
}
var red = Convert.ToInt32(r * 255);
var green = Convert.ToInt32(g * 255);
var blue = Math.Abs(Convert.ToInt32(b * 255));
return Color.FromArgb(red, green, blue);
}
}

可单独使用,如
Color color = (new HSB(Color.FromArgb(100, 100, 220)) + new HSB(Color.Tomato)).ToColor();

xuzuning 2015-05-28
  • 打赏
  • 举报
回复
光线和颜料是不一样,但两束红光合起来不还是红光吗?难不成变成了白光
wangtong2010 2015-05-28
  • 打赏
  • 举报
回复
引用 30 楼 xuzuning 的回复:
你拿两管蓝色的水彩色能调出浅蓝色吗? 显然是不能的
那光线呢,光线与颜料应该还不一样吧?
bbjiabcd 2015-05-28
  • 打赏
  • 举报
回复
引用 23 楼 yangb0803 的回复:
額.... 这么写不对么? 沒用多个颜色去测试.
        private void button1_Click(object sender, EventArgs e)
        {
            label1.ForeColor = Color.FromArgb(255, 0, 0);  //红
            label2.ForeColor = Color.FromArgb(0, 255, 0);  //绿

            int rgb1 = ParseRGB(Color.FromArgb(255, 0, 0));
            int rgb2 = ParseRGB(Color.FromArgb(0, 255, 0));
            int rgb3 = rgb1 + rgb2;

            label3.ForeColor = RGB(rgb3);   //黄
        }

        private Color RGB(int color)
        {
            int r = 0xFF & color;
            int g = 0xFF00 & color;
            g >>= 8;
            int b = 0xFF0000 & color;
            b >>= 16;
            return Color.FromArgb(r, g, b);
        }

        private int ParseRGB(Color color)
        {
            return color.B << 16 | color.G << 8 | color.R;
        }
你试试255,255,0 和 1,0,0
xuzuning 2015-05-28
  • 打赏
  • 举报
回复
你拿两管蓝色的水彩色能调出浅蓝色吗? 显然是不能的
wangtong2010 2015-05-28
  • 打赏
  • 举报
回复
还有一个问题,真实世界中,两种相同颜色的彩光混合(亮度也一样),得到的是新颜色,还是原来的颜色?
按照我的算法是新颜色(如下图),按照17楼的算法是原来的颜色。
wangtong2010 2015-05-28
  • 打赏
  • 举报
回复
引用 19 楼 tcmakebest 的回复:
我研究的光色叠加计算公式
private Color AddColor(Color color, Color color_2)
{
    int[] cv = new int[]{
        color.R,color.G,color.B,
        color_2.R,color_2.G,color_2.B,
        0,0,0
    };
    for (int i = 0; i < 3; i++)
    {
        cv[i + 6] = 255 - (255 - cv[i + 0]) * (255 - cv[i + 3]) / 255;
    }
    return Color.FromArgb(cv[6], cv[7], cv[8]);
}
您的算法与我的算法(12楼)是一样的,真是异曲同工啊。
失落的神庙 2015-05-27
  • 打赏
  • 举报
回复
要么就画在一个bitmap上。 然后 获取一个色点的rgb 值。
失落的神庙 2015-05-27
  • 打赏
  • 举报
回复
r1,g1,b1, r2,g2,b2 先试试 (r1+r2)/2 (g1+g2)/2 (b1+b2)/2
xuzuning 2015-05-27
  • 打赏
  • 举报
回复
一束红光与一束黄光垒加,黄光将湮没红光 事实上是黄偏红,应该叫着什么橙 光的混合是一个物理现象,不能用简单的数学式表达 所以 PS 不就提供了十多种混色方案供你模拟逼真的效果,并可产生自然界并不存在的色彩效果
於黾 2015-05-27
  • 打赏
  • 举报
回复
引用 12 楼 wangtong2010 的回复:
这样的计算方法是否真实? R=R1+R2-R1*R2/255 G=G1+G2-G1*G2/255 B=B1+B2-B1*B2/255 按照这样的算法,一束红光与一束黄光垒加,黄光将湮没红光,真实情况是这样吗?
楼主给出了三基色混光的图 可以看出,红+绿=黄 那么可以说黄是包含红的 黄和红混光之后,就是应该泯没红光 当然真实情况不仅要看2种光的色调,还要看各自的光强度,如果黄光很弱,而红光很强,整体应该表现为红色,黄色基本看不出 所以只用RGB,而A不参与计算,跟真实情况肯定是有出入的
bbjiabcd 2015-05-27
  • 打赏
  • 举报
回复
各分量相加,大于255的就设成255
於黾 2015-05-27
  • 打赏
  • 举报
回复
引用 23 楼 yangb0803 的回复:
額....
用三基色测试好像挺对的 但是我换成128,0,0和128,0,0,你再看? 淡红色和淡红色放一起,会变成纯红色?
道玄希言 2015-05-27
  • 打赏
  • 举报
回复
額....


这么写不对么? 沒用多个颜色去测试.
        private void button1_Click(object sender, EventArgs e)
{
label1.ForeColor = Color.FromArgb(255, 0, 0); //红
label2.ForeColor = Color.FromArgb(0, 255, 0); //绿

int rgb1 = ParseRGB(Color.FromArgb(255, 0, 0));
int rgb2 = ParseRGB(Color.FromArgb(0, 255, 0));
int rgb3 = rgb1 + rgb2;

label3.ForeColor = RGB(rgb3); //黄
}

private Color RGB(int color)
{
int r = 0xFF & color;
int g = 0xFF00 & color;
g >>= 8;
int b = 0xFF0000 & color;
b >>= 16;
return Color.FromArgb(r, g, b);
}

private int ParseRGB(Color color)
{
return color.B << 16 | color.G << 8 | color.R;
}




xuzuning 2015-05-27
  • 打赏
  • 举报
回复
#19 的在 Photoshop 称为 Screen 滤色模式 #21 的在 Photoshop 称为 Linear Dodge 线性减淡(只是不知越界处理方案是否也一样)
bbjiabcd 2015-05-27
  • 打赏
  • 举报
回复
提供一种算法,各分量的和小于255则直接相加,有大于255的分量则相加后按比例缩小

    class LightColor
    {
        Color color;

        public Color Color1
        {
            get { return color; }
            set { color = value; }
        }
        public LightColor() { }
        public LightColor(Color color)
        {
            this.color = color;
        }
        public static LightColor operator +(LightColor lightColor1,LightColor lightColor2)
        {
            int red = lightColor1.color.R + lightColor2.color.R;
            int green = lightColor1.color.G + lightColor2.color.G;
            int blue = lightColor1.color.B + lightColor2.color.B;
            int max = Math.Max(Math.Max(red, green), blue);
            if (max > 255)
            {
                double f = 255.0 / max;
                red = (int)(red * f);
                green = (int)(green * f);
                blue = (int)(blue * f);
            }
            LightColor lightColor = new LightColor(Color.FromArgb(red,green,blue));
            return lightColor;
        }
    }
tcmakebest 2015-05-27
  • 打赏
  • 举报
回复
我研究的光色叠加计算公式
private Color AddColor(Color color, Color color_2)
{
    int[] cv = new int[]{
        color.R,color.G,color.B,
        color_2.R,color_2.G,color_2.B,
        0,0,0
    };
    for (int i = 0; i < 3; i++)
    {
        cv[i + 6] = 255 - (255 - cv[i + 0]) * (255 - cv[i + 3]) / 255;
    }
    return Color.FromArgb(cv[6], cv[7], cv[8]);
}
BrightFireOfCy 2015-05-26
  • 打赏
  • 举报
回复
光谱混合算法,这个涉及到很多物理学的东西,搞不懂,帮顶
加载更多回复(12)

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧