2016-03-01 100 views
0

如何将一系列颜色映射到一系列整数?如何将一系列颜色映射到整数范围?

具体来说,我希望滑块从深绿色变为黄色变为红色。

以下代码仅为颜色添加阴影。

XAML:

<Window x:Class="MotoLens.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:MotoLens" 
     mc:Ignorable="d" 
     Background="Black" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 
     <local:ValueToBrushConverter x:Key="ValueToBrushConverter" /> 
    </Window.Resources> 
    <Grid> 
     <Slider x:Name="Slider" Grid.Row="0" Minimum="0" Maximum="200" Background="{Binding RelativeSource={RelativeSource Self}, Path=Value, Converter={StaticResource ValueToBrushConverter}, ConverterParameter=0~200}" 
       TickFrequency="1" IsSnapToTickEnabled="True" TickPlacement="TopLeft" /> 
    </Grid> 
</Window> 

ValueConverter:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
{ 
    var args = parameter as string; 
    var minimumInput = int.Parse(args?.Split('~')?[0]); 
    var maximumInput = int.Parse(args?.Split('~')?[1]); 

    var currentValue = (double)value; 
    var colorValue = (int)255 - (currentValue * (COLOR_RANGE_MAX/maximumInput)); 
    var color = Color.FromArgb(COLOR_RANGE_MAX, 0, System.Convert.ToByte(colorValue), 0); 
    return new SolidColorBrush(color); 
} 

注: 我的记忆告诉我,我应该让框架通过动画为我做的。 不确定它是彩色动画还是双动画。

通过回答更新时间:

namespace MotoLens 
{ 
    class ValueToBrushConverter : IValueConverter 
    { 
     static readonly Color[] _colorTable = 
      { 
      Color.FromRgb( 0, 255, 255), 
      Color.FromRgb( 0, 255, 0), 
      Color.FromRgb(255, 255, 0), 
      Color.FromRgb(255, 0, 0), 
      }; 

     public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      var args = parameter as string; 
      var minimumInput = int.Parse(args.Split('~')[0]); 
      var maximumInput = int.Parse(args.Split('~')[1]); 

      var currentValue = ((double)value - minimumInput)/(maximumInput - minimumInput); 
      var col1 = (int)(currentValue * (_colorTable.Length - 1)); 
      var col2 = Math.Min(col1 + 1, (_colorTable.Length - 1)); 

      var t = 1.0/(_colorTable.Length - 1); 
      return new SolidColorBrush(Lerp(_colorTable[col1], _colorTable[col2], (currentValue - t * col1)/t)); 
     } 

     public static Color Lerp(Color col1, Color col2, double t) 
     { 
      var r = col1.R * (1 - t) + col2.R * t; 
      var g = col1.G * (1 - t) + col2.G * t; 
      var b = col1.B * (1 - t) + col2.B * t; 
      return Color.FromRgb((byte)r, (byte)g, (byte)b); 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 
    } 
} 

回答

1

试试这个:

private static readonly Color[] ColorTable = 
    { 
     Color.FromRgb(255, 0, 0), 
     Color.FromRgb(255, 255, 0), 
     Color.FromRgb( 0, 255, 0), 
     Color.FromRgb( 0, 255, 255), 
     Color.FromRgb( 0, 0, 255), 
     Color.FromRgb(255, 0, 255), 
     Color.FromRgb(255, 0, 0), 
    }; 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    {   
     var args = parameter as string; 
     var minimumInput = int.Parse(args.Split('~')[0]); 
     var maximumInput = int.Parse(args.Split('~')[1]); 
     var currentValue = ((double)value - minimumInput)/(maximumInput - minimumInput); 
     var col1 = (int)(currentValue * (ColorTable.Length-1)); 
     var col2 = Math.Min(col1+1, (ColorTable.Length-1)); 
     var t = 1.0/(ColorTable.Length - 1); 
     return new SolidColorBrush(Lerp(ColorTable[col1], ColorTable[col2], (currentValue - t *col1)/t)); 
    } 

    public static Color Lerp(Color col1, Color col2, double t) 
    { 
     var r = col1.R * (1-t) + col2.R * t; 
     var g = col1.G * (1-t) + col2.G * t; 
     var b = col1.B * (1-t) + col2.B * t; 
     return Color.FromRgb((byte)r, (byte)g, (byte)b); 
    } 
+0

请看我更新的帖子。 –

+0

那么问题得到了满意的回答?还是有其他要求?顺便说一句我[这篇文章]的答案(http://stackoverflow.com/questions/32513387/how-to-create-a-color-canvas-for-color-picker-wpf)关于颜色选择器可能也有兴趣在这种情况下,您通常会使用诸如色相栏之类的东西作为滑块的背景。 –

+0

是的。现在我有一个新的问题:http://stackoverflow.com/questions/35760507/how-can-i-create-a-gauge-i-e-speedometer –

0

根据我的ColorExtensions有从HSL或HSV转换为RGB格式的方法你可以做一些事情。例如。

#region FromHsv() 
/// <summary> 
/// Returns a Color struct based on HSV model. 
/// </summary> 
/// <param name="hue">0..360 range hue</param> 
/// <param name="saturation">0..1 range saturation</param> 
/// <param name="value">0..1 range value</param> 
/// <param name="alpha">0..1 alpha</param> 
/// <returns></returns> 
public static Color FromHsv(double hue, double saturation, double value, double alpha = 1.0) 
{ 
    Debug.Assert(hue >= 0); 
    Debug.Assert(hue <= 360); 

    double chroma = value * saturation; 
    double h1 = hue/60; 
    double x = chroma * (1 - Math.Abs(h1 % 2 - 1)); 
    double m = value - chroma; 
    double r1, g1, b1; 

    if (h1 < 1) 
    { 
     r1 = chroma; 
     g1 = x; 
     b1 = 0; 
    } 
    else if (h1 < 2) 
    { 
     r1 = x; 
     g1 = chroma; 
     b1 = 0; 
    } 
    else if (h1 < 3) 
    { 
     r1 = 0; 
     g1 = chroma; 
     b1 = x; 
    } 
    else if (h1 < 4) 
    { 
     r1 = 0; 
     g1 = x; 
     b1 = chroma; 
    } 
    else if (h1 < 5) 
    { 
     r1 = x; 
     g1 = 0; 
     b1 = chroma; 
    } 
    else //if (h1 < 6) 
    { 
     r1 = chroma; 
     g1 = 0; 
     b1 = x; 
    } 

    byte r = (byte)(255 * (r1 + m)); 
    byte g = (byte)(255 * (g1 + m)); 
    byte b = (byte)(255 * (b1 + m)); 
    byte a = (byte)(255 * alpha); 

    return Color.FromArgb(a, r, g, b); 
} 
#endregion 

示例 - XAML:

<StackPanel> 
    <Slider 
     x:Name="HueSlider" 
     Minimum="0" 
     Maximum="360" 
     StepFrequency="1" 
     ValueChanged="HueSlider_ValueChanged" /> 
    <Rectangle 
     x:Name="HueRect" 
     Width="400" 
     Height="200" /> 
</StackPanel> 

后面的代码:

private void HueSlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e) 
{ 
    HueRect.Fill = new SolidColorBrush(
     FromHsv(e.NewValue, 1, 1)); 
} 
+0

感谢。但我不确定如何使用它来将整数值映射到通过min和max的颜色。 –

+0

HSV模型具有更容易操作以获得与RGB不同的颜色的色调组件。您可以调用'FromHsv(hue,1,1)'作为0..1的色调值以获得不同的颜色值。对于0到255的int色调值,你可以调用'FromHsv((double)hue/255,1,1)',但是'Slider'控件给你'double'输入'Value'而不是'int'所以你可以使用它。 –

+0

其实,划伤 - 范围是0..360,所以你不必分割任何东西。 –