转载自:blog.sina.com.cn/s/blog_8780… 最近因为项目需要,我需要得到一个颜色和数值的映射关系。这个映射关系是什么意思呢?下面的图1是这种映射关系的一种直观的反映。
RGB颜色和数值的映射关系
图1
在图1中,可以看作标尺上的每个数值对应一种颜色。并且,由于标尺的值是连续的,而不是离散的,所以颜色的变化也应该是连续的,而不应该是离散地变化。
起初,我以为这种映射关系应该是一种行业规范,于是就直接在网上查看能不能找到这个规范或者是生成这种映射关系的函数。可是该如何描述这个东西呢?虽然我给它的定义是“颜色和数值的映射关系”,可是它在网络资源里面真的就叫这个名字么...果然,采用上面的关键词进行搜索,没有得到满意的效果。于是又采用了其它的一些关键词,都没有搜出相关的文档出来。抱着最后的希望,试了Google,Baidu的content based image search,估计是图片库里没有这个东西,所以还是没有搜出来。没办法,只能自己搞了。
突然发现这个颜色的变化其实是有规律的。最下面的是黑色,上面是蓝色,在上面是绿色...中间的一些颜色应该是根据纯蓝色,纯绿色,纯红色这三个颜色混合而来的。于是,我根据这个猜测试了一下。这个标尺有21个刻度(我指的是整数刻度),我计算了每个刻度处的颜色值。保存在下面的数组中。
float Color[21][3] = { {0,0,0},{0,0,0.25},{0,0,0.5},{0,0,0.75},{0,0,1}, {0,0.25,1},{0,0.5,1},{0,0.75,1},{0,1,1},{0,1,0.75}, {0,1,0.5},{0,1,0.25},{0,1,0},{0.25,1,0},{0.5,1,0}, {0.75,1,0},{1,1,0},{1,0.5,0},{1,0,0},{1,0,0.5},{1,0,1} };
这样,这20个刻度对应的颜色值就出来了。但是中间的值应该如何获得呢?这个其实不用担心,OPENGL提供了GL_SMOOTH的着色模式,它会通过渐变的方式填充两个已经着色的点之间的颜色。当然,还可以通过另外一种方式来实现。这就是OPENGL提供的颜色混合方式。假设有两个已经着色的点A(颜色为(RA,GA,BA)),点B(颜色为(RB,GB,BB)),假设点C位于A和B之间。那么点C应该如何着色呢?一个直观的认识是:点C离A,B之间哪个点越近,那么C的颜色就应该越接近于最近的那个点。以D(A,C)作为AC间的距离,D(B,C)作为BC间的距离,那么着色因子可以定义为F(A,C)=D(B,C)/(D(A,C)+D(B,C));F(B,C)=D(A,C)/(D(A,C)+D(B,C))。C的颜色可以表示为(RAF(A,C)+RBF(B,C),GAF(A,C)+GBF(B,C),BAF(A,C)+BBF(B,C))。我用这种方式做了一下,发现和采用OPENGL提供的平滑着色模式的结果是一致的。估计平滑着色模式也是这样实现的吧。
这里贴一张通过上面的方法得到的效果图。
RGB颜色和数值的映射关系
图2
方法二:转载自:www.cnblogs.com/enjoyeclips…
/// 根据温度获取颜色
/// 算法如下:
/// 1.定义色阶变化范围fromColor, toColor
/// 2.获取因子:factor = T / (MaxT - MinT);
/// 3.计算新的RGB
/// R = fromColor.R * (1 - factor) + toColor.R * factor
/// G = fromColor.G * (1 - factor) + toColor.G * factor
/// B = fromColor.B * (1 - factor) * toColor.B * factor
/// 4.如果多个色阶,重复上面的运算
/// </summary>
public static class TemperatuerColor
{
private static Color Red = Color.FromRgb(255, 0, 0);
private static Color Yellow = Color.FromRgb(255, 0, 0);
private static Color Blue = Color.FromRgb(255, 0, 0);
public static SolidColorBrush GetColor(double temperature, double maxtemperature, double mintemperature)
{ double ratio = temperature / (maxtemperature - mintemperature);
Color result1 = Compute(Blue, Yellow, ratio);
Color result2 = Compute(Yellow, Red, ratio);
Color result = Compute(result1, result2, ratio);
return new SolidColorBrush(result);
}
private static Color Compute(Color fromColor, Color toColor, double ratio){
byte r = (byte)(fromColor.R * (1.0f - ratio) + toColor.R * ratio);
byte g = (byte)(fromColor.G * (1.0f - ratio) + toColor.G * ratio);
byte b = (byte)(fromColor.B * (1.0f - ratio) + toColor.B * ratio);
return Color.FromRgb(r, g, b);
}
}