【问题标题】:How to change color hue in XNA?如何更改 XNA 中的色调?
【发布时间】:2012-07-11 13:36:28
【问题描述】:

我的颜色是Microsoft.Xna.Framework.Color。如何更改其色调(或获得色调略有不同的新颜色)。我应该将其转换为System.Drawing.Color,然后以某种方式更改并转换回来吗?我在任何地方都找不到任何有用的信息。

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

【问题讨论】:

  • 那么,您的 Microsoft.XNA.Framework.Color 似乎以 RGB 表示。如果您想要另一种表示,则可以了解该表示的工作原理并编写一个函数来计算 RGB 值。
  • 我不相信真的有一种简单的方法可以做到这一点,但根据维基百科,可以从 RGB 计算颜色的色调(en.wikipedia.org/wiki/Hue#Computing_hue_from_RGB)我不知道你是否可以不过,从 Hue 到 RGB 很容易。

标签: c# colors xna argb


【解决方案1】:

您应该使用 A R G B 属性并更改值以获得不同的 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);

【讨论】:

  • 谢谢,我正在检查这个解决方案。
  • 当我在Increase() 方法中将&gt;= 切换为&lt;= 时,它工作得很好。否则它只会停在一种颜色上 - 在#FF0000 上尝试您的代码。当我纠正它时,它正在改变颜色,但不是全光谱。无论如何,谢谢和+1 :)。
【解决方案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 是最常见的,但还有其他表示)

如果您想将 Hue 转换为 RBG Here is a guide on how to do it

最简单的方法可能是跟踪 System.Drawing.Color 类作为您的基本颜色类,并根据您的 System.Drawing.Color 类相应地修改您的 XNA Color 类。

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

【讨论】:

  • 但是我需要稍微改变一下我的颜色。例如,从橙色到红色。不是从头开始定义颜色。
  • @Episodex 然后只需修改 RBG 属性
  • 你的例子很好地解决了我的例子。但它不是通用的:(。我不能将它与其他颜色组合一起使用,所有起始颜色都是可能的。我会尝试转换为System.Drawing.Color
  • 我认为更像color.Hue += 10,因为据我所知,色调是 0 到 360 之间的数字。
  • @Episodex 我刚刚在我的回答中发布了指向cs.rit.edu/~ncs/color/t_convert.html 的链接。它具有从 HSV(基于色调)转换为 RBG 的算法。您应该能够使用它来获得您想要的表示
【解决方案3】:

我做了一些研究,发现这篇文章有 C++ 代码:

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

我已将代码修改为 C#,添加了 IncreaseHueBy 方法,并修复了一些错误:

 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 对其进行了测试,并且效果相当好。请注意可能存在一些舍入错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-17
    • 2016-07-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多