2012-07-11 69 views
4

我有一个颜色类Microsoft.Xna.Framework.Color。我怎样才能改变它的色调(或者以略微不同的色调来获得新的颜色)。我应该将其转换为System.Drawing.Color,然后以某种方式更改并转换回来?我无法在任何地方找到任何有用的信息。如何更改XNA中的色调?

EDIT 实施例: 我有红色R:255,G:0,B:0。现在我想要获得更多的橙色。然后,如果我获得了这种颜色并再次转换,我会得到更多的橙色,然后经过一些转换后,我会去黄色,绿色等。我不知道每种颜色的ARGB的确切值,我不需要他们。我只需要通过一些因素(例如10度)来改变颜色的色调。

+1

那么,你的Microsoft.XNA.Framework.Color似乎用RGB表示。如果您想要另一种表示,则可以了解该表示如何工作,然后编写一个函数来计算基于此值的RGB值。 – 2012-07-11 20:54:15

+0

我不认为有这样做的简单方法,但根据维基百科,可以计算RGB颜色的色相(http://en.wikipedia.org/wiki/Hue#Computing_hue_from_RGB) I不知道你是否可以轻松地从Hue转到RGB。 – gb92 2012-07-12 02:42:49

回答

2

根据this documentation,你可以传递你想要的任何RGB(A)值到XNA颜色类的构造函数中。您也可以使用R,B和G性质改变他们事后

例如:

Color myColor = new Color(150, 100, 100); 

myColor.R = 200 

这个例子将改变一个红色的略深的红色。

使颜色从红色到橙色到黄色到绿色将

Color myColor = new Color(255, 0, 0); 

for(int i=0; i<255; i++) 
{ 
    myColor.R--; 
    myColor.G++ 
} 

红色和绿色制造的红,黄,号码,以便提高将使其更红,绿的数字更高将使的例子它更绿。两个数字相同使它更红。

只要您知道光的基色如何工作,您也可以用其他方式递增地改变颜色。
你永远会找到一个叫Color.MakeRedder()Color.MakeGreener()功能将始终专注于某种颜色的工科数学表示,(RBG是最常见的,但也有其他表示)

如果你想转换色调RBG Here is a guide on how to do it

什么很可能是最简单的就是保持System.Drawing.Color类作为您的基色类的轨迹,并根据您的XNA Color类您System.Drawing.Color类进行相应的修改。

如果你想变得非常冒险,你可以看看是否可以创建一个扩展(继承自Microsoft.Xna.Framework.Color)的类,覆盖R,G和B属性,以便它们基于底层System.Drawing.Color对象

+0

但我需要稍微改变我的颜色的色调。所以从橙色到更红色的例子。没有从头开始定义颜色。 – Episodex 2012-07-11 20:43:14

+0

@Episodex然后只是修改RBG属性 – 2012-07-11 20:46:34

+0

我必须编辑我的问题,使自己更清楚:)。 – Episodex 2012-07-11 20:47:55

6

您应该使用ARGB属性并更改值以获取不同的nyansers。

例如:

Color color = new Color(0,0,0); 
//Then you can change the argb properties: 
color.A = 10; 
color.R = 15; 
color.G = 9; 
color.B = 25; 

如果我理解你需要的东西是这样的:

public static class Utilities 
{ 
    public static void Increase(this Color color, int value) 
    { 
     if(color.R >= color.G && color.R >= color.B) 
      color.R += value; 
     else if(color.G >= color.R && color.G >= color.B) 
      color.G += value; 
     else 
      color.B += value; 
    } 

    public static void Decrease(this Color color, int value) 
    { 
     if(color.R <= color.G && color.R <= color.B) 
      color.R -= value; 
     else if(color.G <= color.R && color.G <= color.B) 
      color.G -= value; 
     else 
      color.B -= value; 
    } 
} 

然后:

Color myColor = new Color(10,0,0); 
myColor.Increase(10); 
//or 
myColor.Decrease(10); 
+0

请检查我的编辑。 – Episodex 2012-07-11 20:52:26

+0

我编辑了我的答案。 – 2012-07-11 21:08:18

+0

谢谢,我正在检查此解决方案。 – Episodex 2012-07-11 21:19:12

0

我做了一些研究,发现这个帖子里面有C++代码:

http://www.cs.rit.edu/~ncs/color/t_convert.html

我已经修改了代码为C#,有一个IncreaseHueBy方法,并修复一些bug:

public static void IncreaseHueBy(ref Color color, float value, out float hue) 
{ 
    float h, s, v; 

    RgbToHsv(color.R, color.G, color.B, out h, out s, out v); 
    h += value; 

    float r, g, b; 

    HsvToRgb(h, s, v, out r, out g, out b); 


    color.R = (byte)(r); 
    color.G = (byte)(g); 
    color.B = (byte)(b); 

    hue = h; 
} 

static void RgbToHsv(float r, float g, float b, out float h, out float s, out float v) 
{ 
    float min, max, delta; 
    min = System.Math.Min(System.Math.Min(r, g), b); 
    max = System.Math.Max(System.Math.Max(r, g), b); 
    v = max;    // v 
    delta = max - min; 
    if (max != 0) 
    { 
     s = delta/max;  // s 

     if (r == max) 
      h = (g - b)/delta;  // between yellow & magenta 
     else if (g == max) 
      h = 2 + (b - r)/delta; // between cyan & yellow 
     else 
      h = 4 + (r - g)/delta; // between magenta & cyan 
     h *= 60;    // degrees 
     if (h < 0) 
      h += 360; 
    } 
    else 
    { 
     // r = g = b = 0  // s = 0, v is undefined 
     s = 0; 
     h = -1; 
    } 

} 
static void HsvToRgb(float h, float s, float v, out float r, out float g, out float b) 
{ 
    // Keeps h from going over 360 
    h = h - ((int)(h/360) * 360); 

    int i; 
    float f, p, q, t; 
    if (s == 0) 
    { 
     // achromatic (grey) 
     r = g = b = v; 
     return; 
    } 
    h /= 60;   // sector 0 to 5 

    i = (int)h; 
    f = h - i;   // factorial part of h 
    p = v * (1 - s); 
    q = v * (1 - s * f); 
    t = v * (1 - s * (1 - f)); 
    switch (i) 
    { 
     case 0: 
      r = v; 
      g = t; 
      b = p; 
      break; 
     case 1: 
      r = q; 
      g = v; 
      b = p; 
      break; 
     case 2: 
      r = p; 
      g = v; 
      b = t; 
      break; 
     case 3: 
      r = p; 
      g = q; 
      b = v; 
      break; 
     case 4: 
      r = t; 
      g = p; 
      b = v; 
      break; 
     default:  // case 5: 
      r = v; 
      g = p; 
      b = q; 
      break; 
    } 
} 

我测试了它的值为1,每帧增加1,色调相当好。注意可能会有一些舍入错误。