首页 > 学院 > 开发设计 > 正文

#673 – 将鼠标位置和颜色进行映射(Mapping Mouse Position to Color)

2019-11-06 06:13:24
字体:
来源:转载
供稿:网友

我们可以将鼠标的位置信息隐射成颜色的色调和饱和度,然后将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的值。我们可以通过其他方式来映射改变亮度是值,比如鼠标通过滚轮增加和减少亮度。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表