我们可以将鼠标的位置信息隐射成颜色的色调和饱和度,然后将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的值。我们可以通过其他方式来映射改变亮度是值,比如鼠标通过滚轮增加和减少亮度。