为什么Alpha“FromArgb”会在LinearGradientBrush中出现问题?

时间:2016-08-26 02:01:35

标签: c# colors

我想使用彩虹色生成带有100个GradientStops的public static LinearGradientBrush CreateRainbowBrush() { var brush = new LinearGradientBrush { StartPoint = new System.Windows.Point(0, 0), EndPoint = new System.Windows.Point(1, 0) }; int colorCount = 100; double step = 1 / colorCount; List<Color> rainbow = GetRainbowColors(colorCount); for (int i = 0; i < colorCount; i++, step += step) { brush.GradientStops.Add(new GradientStop(rainbow.ElementAt(i) , step); } return brush; }

这样做我正在做

FFFF0000
FFFF03D0
...

问题是以下方法返回的值如

FFFF00
FFFF03

这些都是正确的,但我想通了,当我用自己的方法使用时,我会得到灰度,就像我会采取

public static List<Color> GetRainbowColors(int colorCount)
    {
        List<Color> ret = new List<Color>(colorCount);

        double p = 360.0 / (double)colorCount;

        for (int n = 0; n < colorCount; n++)
        {
            ret.Add(HsvToRgb(n * p, 1.0, 1.0));
        }

        return ret;
    }
    public static Color HsvToRgb(double h, double s, double v)
    {
        int hi = (int)Math.Floor(h / 60.0) % 6;
        double f = (h / 60.0) - Math.Floor(h / 60.0);

        double p = v * (1.0 - s);
        double q = v * (1.0 - (f * s));
        double t = v * (1.0 - ((1.0 - f) * s));

        Color ret;

        switch (hi)
        {
            case 0:
                ret = GetRgb(v, t, p);
                break;
            case 1:
                ret = GetRgb(q, v, p);
                break;
            case 2:
                ret = GetRgb(p, v, t);
                break;
            case 3:
                ret = GetRgb(p, q, v);
                break;
            case 4:
                ret = GetRgb(t, p, v);
                break;
            case 5:
                ret = GetRgb(v, p, q);
                break;
            default:
                ret = Color.FromRgb(0x00, 0x00, 0x00);
                break;
        }
        ret = Color.FromRgb (ret.R, ret.G, ret.B);
        return ret;
    }
    public static Color GetRgb(double r, double g, double b)
    {
        return Color.FromRgb ((byte)(r * 255.0), (byte)(g * 255.0), (byte)(b * 255.0));
    }

这是不正确的

将色调转换为颜色的代码是:

var vCard = (function () {
    var start = "BEGIN:VCARD\nVERSION:3.0";
    var end = "END:VCARD";
    var data = "";

    var init = function() {
        data = "";
    };

    var name = function (surname, lastname) {
        data += "N:" + lastname + ';' + surname;
        data += "\n";
    };

    var cell = function (cell) {
        data += "TEL;TYPE=CELL:" + cell;
        data += "\n";
    };

    var work = function (work) {
        data += "TEL;TYPE=WORK,VOICE:" + work;
        data += "\n";
     };

    var other = function (work) {
        data += "TEL;TYPE=OTHER:" + work;
        data += "\n";
    };

    var email = function (email) {
        data += "EMAIL;TYPE=PREF,INTERNET:" + email;
        data += "\n";
    };

    var get = function () {
        return start + '\n' + data + end;
    };

    return {
        init:init,
        name:name,
        cell:cell,
        work:work,
        other:other,
        email:email,
        get:get
    }
});

我错过了什么,如何从rgb中删除 a

2 个答案:

答案 0 :(得分:2)

您的算法的H范围为0到360!

enter image description here

using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;

namespace WpfApplication4
{
    public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();
            Loaded += MainWindow_Loaded;
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            var rectangle = new Rectangle();
            rectangle.Fill = CreateRainbowBrush(100);
            Content = rectangle;
        }

        public static LinearGradientBrush CreateRainbowBrush(int colors)
        {
            var brush = new LinearGradientBrush
            {
                StartPoint = new Point(0, 0),
                EndPoint = new Point(1, 0)
            };

            for (var i = 0; i < colors; i++)
            {
                var d = 1.0d/colors*i;
                var h = d*360.0d;
                var s = 1.0d;
                var v = 1.0d;
                var hsvToRgb = HsvToRgb(h, s, v);
                brush.GradientStops.Add(new GradientStop(hsvToRgb, d));
            }
            return brush;
        }

        public static Color HsvToRgb(double h, double s, double v)
        {
            var hi = (int) Math.Floor(h/60.0)%6;
            var f = h/60.0 - Math.Floor(h/60.0);

            var p = v*(1.0 - s);
            var q = v*(1.0 - f*s);
            var t = v*(1.0 - (1.0 - f)*s);

            switch (hi)
            {
                case 0:
                    return ToColor(v, t, p);
                case 1:
                    return ToColor(q, v, p);
                case 2:
                    return ToColor(p, v, t);
                case 3:
                    return ToColor(p, q, v);
                case 4:
                    return ToColor(t, p, v);
                case 5:
                    return ToColor(v, p, q);
                default:
                    return Colors.Black;
            }
        }

        public static Color ToColor(double r, double g, double b)
        {
            return Color.FromRgb((byte) (r*255.0), (byte) (g*255.0), (byte) (b*255.0));
        }
    }
}

答案 1 :(得分:0)

我没有花太多时间试图找出代码中的具体问题。您发布的代码无法编译,一旦我运行它,我发现生成的每个Color值都具有0xff的alpha值,正如预期的那样。我不知道如何解释你的问题:

  

如何从rgb中移除 a !?

删除怎么样?你在谈论&#34; a &#34; 是什么意思?

我确实注意到了各种数学上的不规则性,但似乎需要从头开始重新编写算法以缩小特定问题(尽管我看到其他人做了,并且也明显清理了你的代码)。

主要是,在我看来,你这一切都是错的。没有理由创建这么多停靠点,因为WPF会很乐意为您插入原始颜色。并且没有必要编写代码来执行此操作,因为您可以轻松地在XAML中声明整个内容:

<Window x:Class="TestSO39157294Rainbow.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:TestSO39157294Rainbow"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">

    <Window.Resources>
        <LinearGradientBrush x:Key="rainbowBrush" StartPoint="0,0" EndPoint="1,0">
            <GradientStop Color="Red" Offset="0"/>
            <GradientStop Color="Yellow" Offset="0.16667"/>
            <GradientStop Color="Lime" Offset="0.33333"/>
            <GradientStop Color="Cyan" Offset="0.5"/>
            <GradientStop Color="Blue" Offset="0.66666"/>
            <GradientStop Color="Magenta" Offset="0.83333"/>
            <GradientStop Color="Red" Offset="1"/>
        </LinearGradientBrush>
    </Window.Resources>

    <Rectangle Fill="{StaticResource rainbowBrush}"/>
</Window>