13

私は次のものを持っていますGradientStopCollection

GradientStopCollection grsc = new GradientStopCollection(3);
grsc.Add(new GradientStop(Colors.Red, 0));
grsc.Add(new GradientStop(Colors.Yellow, .5));
grsc.Add(new GradientStop(Colors.Green, 1));

特定の「場所」で色を取得できますか? 例えば:

  • ロケーション 0: 赤
  • 場所 .5: 黄色
  • ロケーション .75:Yellow<~>Green

WPFそれを行うことができる/いくつかのサードパーティライブラリにAPIがありますか?

4

3 に答える 3

19

問題のグラデーションを理解するには、特定のポイントで色を取得する必要がありますが、これはクラス GradientStopCollection の役割ではありません。このクラスの概念はグラデーションを理解することではなく、グラデーションをサポートする単純なコレクションである必要があります。

各クラスの概念を理解することが重要です。

色を取得するには、グラデーションを使用してペイントするグラデーションを表すクラスをインスタンス化し、最終的にペイントから色を取得する必要があります。

しかし、より迅速な解決策を提供します。勾配アルゴリズムを使用して、単一の点を生成できます。これは、線形勾配アルゴリズムを使用してこれを行う方法の実装です。

public static class GradientStopCollectionExtensions
{
    public static Color GetRelativeColor(this GradientStopCollection gsc, double offset)
    {
        var point = gsc.SingleOrDefault(f => f.Offset == offset);
        if (point != null) return point.Color;

        GradientStop before = gsc.Where(w => w.Offset == gsc.Min(m => m.Offset)).First();
        GradientStop after = gsc.Where(w => w.Offset == gsc.Max(m => m.Offset)).First();

        foreach (var gs in gsc)
        {
            if (gs.Offset < offset && gs.Offset > before.Offset)
            {
                before = gs;
            }
            if (gs.Offset > offset && gs.Offset < after.Offset)
            {
                after = gs;
            }
        }

        var color = new Color();

        color.ScA = (float)((offset - before.Offset) * (after.Color.ScA - before.Color.ScA) / (after.Offset - before.Offset) + before.Color.ScA);
        color.ScR = (float)((offset - before.Offset) * (after.Color.ScR - before.Color.ScR) / (after.Offset - before.Offset) + before.Color.ScR);
        color.ScG = (float)((offset - before.Offset) * (after.Color.ScG - before.Color.ScG) / (after.Offset - before.Offset) + before.Color.ScG);
        color.ScB = (float)((offset - before.Offset) * (after.Color.ScB - before.Color.ScB) / (after.Offset - before.Offset) + before.Color.ScB);

        return color;
    }
}

PS:このアルゴリズムは、同じオフセットを持つストップがないことを前提としています。同じオフセットを持つストップが複数ある場合は、 aInvalidOperationExceptionがスローされます。

このクラスを現在のコンテキスト (名前空間コンテキスト) に追加します

任意の場所に色を付けるには、次のように挿入します。

var color = grsc.GetRelativeColor(.75);
于 2012-03-10T23:21:35.443 に答える