我们可以将鼠标的位置信息隐射成颜色的色调和饱和度,然后将HSV颜色值转换为RGB颜色值(我们将亮度值设为1.0)。我们将鼠标位置和中心点连线的角度作为色调值,将鼠标和中心点的距离作为饱和度值。这个图像模型如下图:
下面的代码中我们有一个400*400的Canvas,取鼠标在其上面的位置算出一个颜色显示在Label中。
<Window Name="win1" x:Class="Wpfapplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/PResentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Color from Mouse Position" SizeToContent="WidthAndHeight" MouseMove="win1_MouseMove_1"> <Canvas x:Name="canv1" Width="400" Height="400"> <Label Content="{Binding RGBInfo}" HorizontalAlignment="Center" /> </Canvas></Window>在后台代码中,我们注册MouseMove 事件,并在里面根据鼠标位置计算颜色,作为背景色显示。
/// <summary>////// Interaction logic for MainWindow.xaml/// </summary>public partial class MainWindow : Window, INotifyPropertyChanged{ SolidColorBrush backBrush = new SolidColorBrush(); public MainWindow() { InitializeComponent(); this.DataContext = this; win1.Background = backBrush; } private string rgbInfo; public string RGBInfo // 用于显示颜色信息的字符串 { get { return rgbInfo; } set { if (value != rgbInfo) { rgbInfo = value; RaisePropertyChanged("RGBInfo"); } } } private void win1_MouseMove_1(object sender, MouseEventArgs e) // 鼠标移动事件,计算颜色 { double radius = (canv1.ActualWidth / 2); Color c = ColorFromMousePosition(e.GetPosition(canv1), radius); backBrush.Color = c; RGBInfo = string.Format("R={0}, G={1}, B={2}", c.R, c.G, c.B); } Color ColorFromMousePosition(Point mousePos, double radius) { // 相对canvas中心点的坐标位置 double xRel = mousePos.X - radius; double yRel = mousePos.Y - radius; // 计算色调, 0-360 double angleRadians = Math.Atan2(yRel, xRel); double hue = angleRadians * (180 / Math.PI); if (hue < 0) hue = 360 + hue; // 饱和度是鼠标到中心点的距离和半径的比值,0-1 double saturation = Math.Min(Math.Sqrt(xRel * xRel + yRel * yRel) / radius, 1.0); byte r, g, b; ColorUtil.HsvToRgb(hue, saturation, 1.0, out r, out g, out b); return Color.FromRgb(r, g, b); } public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged(string prop) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(prop)); }}下面是HSV转换RGB的代码http://www.splinter.com.au/converting-hsv-to-rgb-colour-using-c/
public static class ColorUtil{ /// <summary> /// Convert HSV to RGB /// h is from 0-360 /// s,v values are 0-1 /// r,g,b values are 0-255 /// Based upon http://ilab.usc.edu/wiki/index.php/HSV_And_H2SV_Color_Space#HSV_Transformation_C_.2F_C.2B.2B_Code_2 /// </summary> public static void HsvToRgb(double h, double S, double V, out byte r, out byte g, out byte b) { // ###################################################################### // T. Nathan Mundhenk // mundhenk@usc.edu // C/C++ Macro HSV to RGB double H = h; while (H < 0) { H += 360; }; while (H >= 360) { H -= 360; }; double R, G, B; if (V <= 0) { R = G = B = 0; } else if (S <= 0) { R = G = B = V; } else { double hf = H / 60.0; int i = (int)Math.Floor(hf); double f = hf - i; double pv = V * (1 - S); double qv = V * (1 - S * f); double tv = V * (1 - S * (1 - f)); switch (i) { // Red is the dominant color case 0: R = V; G = tv; B = pv; break; // Green is the dominant color case 1: R = qv; G = V; B = pv; break; case 2: R = pv; G = V; B = tv; break; // Blue is the dominant color case 3: R = pv; G = qv; B = V; break; case 4: R = tv; G = pv; B = V; break; // Red is the dominant color case 5: R = V; G = pv; B = qv; break; // Just in case we overshoot on our math by a little, we put these here. Since its a switch it won't slow us down at all to put these here. case 6: R = V; G = tv; B = pv; break; case -1: R = V; G = pv; B = qv; break; // The color is not defined, we should throw an error. default: //LFATAL("i Value error in Pixel conversion, Value is %d", i); R = G = B = V; // Just pretend its black/white break; } } r = Clamp((byte)(R * 255.0)); g = Clamp((byte)(G * 255.0)); b = Clamp((byte)(B * 255.0)); } /// <summary> /// Clamp a value to 0-255 /// </summary> private static byte Clamp(byte i) { if (i < 0) return 0; if (i > 255) return 255; return i; }}可以看到,随着鼠标的移动,窗口的背景色也不断的变化。
原文地址:https://wpf.2000things.com/2012/10/22/673-mapping-mouse-position-to-color/
******************************************************译者注*******************************************************HSV分别表示的是色调、饱和度和亮度。上面的例子中改变的是色调和饱和度,亮度通常取值为0到1的值。我们可以通过其他方式来映射改变亮度是值,比如鼠标通过滚轮增加和减少亮度。
新闻热点
疑难解答