2016-03-01 78 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,所以你不必分割任何東西。 –

相關問題