本文介绍了WPF中的AngleGradient的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您知道, PhotoShop 中有一个名为AngleGradient的渐变选项.但是,WPF仅具有LinearGradientBrushRadialGradientBrush渐变.您是否知道如何使用XAML创建AngleGradient?

As you know, there is a gradient option in PhotoShop named AngleGradient. But, WPF has only LinearGradientBrush and RadialGradientBrush gradients. Have you any idea to how to create an AngleGradient by using XAML?

更新:示例-通过photoshop:

UPDATE: Samples -by photoshop:

推荐答案

为此我编写了一个着色器,对其进行编译,然后将.ps文件作为资源添加到您的项目中:

I wrote a shader for this, compile it and add the .ps file as a resource to your project:

// no input texture, the output is completely generated in code
sampler2D  inputSampler : register(S0);
/// <summary>The center of the gradient. </summary>
/// <minValue>0,0</minValue>
/// <maxValue>1,1</maxValue>
/// <defaultValue>.5,.5</defaultValue>
float2 centerPoint : register(C0);

/// <summary>The primary color of the gradient. </summary>
/// <defaultValue>Blue</defaultValue>
float4 primaryColor : register(C1);

/// <summary>The secondary color of the gradient. </summary>
/// <defaultValue>Red</defaultValue>
float4 secondaryColor : register(C2);

float4 main(float2 uv : TEXCOORD) : COLOR
{
    float4 src= tex2D(inputSampler, uv);
    float2 p = float2(centerPoint)-uv;
    float angle = (atan2(p.x, p.y) + 3.141596) / (2 * 3.141596);
    float3 f = lerp(primaryColor.rgb, secondaryColor.rgb, angle);
    float4 color = float4(src.a < 0.01 
                                ? float3(0, 0, 0) // WPF uses pre-multiplied alpha everywhere internally for a number of performance reasons.
                                : f, src.a < 0.01 ? 0 : 1);
    return color;
}

像这样包裹它:

public class AngularGradientEffect : ShaderEffect {
    public static readonly DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty(
        "Input", 
        typeof(AngularGradientEffect),
        0);

    public static readonly DependencyProperty CenterPointProperty = DependencyProperty.Register(
        "CenterPoint",
        typeof(Point),
        typeof(AngularGradientEffect), 
        new UIPropertyMetadata(new Point(0.5D, 0.5D), PixelShaderConstantCallback(0)));

    public static readonly DependencyProperty PrimaryColorProperty = DependencyProperty.Register(
        "PrimaryColor", 
        typeof(Color), 
        typeof(AngularGradientEffect), 
        new UIPropertyMetadata(Color.FromArgb(255, 0, 0, 255), PixelShaderConstantCallback(1)));

    public static readonly DependencyProperty SecondaryColorProperty = DependencyProperty.Register(
        "SecondaryColor", 
        typeof(Color),
        typeof(AngularGradientEffect), 
        new UIPropertyMetadata(Color.FromArgb(255, 255, 0, 0), PixelShaderConstantCallback(2)));

    public AngularGradientEffect() {
        PixelShader pixelShader = new PixelShader();
        pixelShader.UriSource = new Uri("/So.Wpf;component/Effects/AngularGradientEffect.ps", UriKind.Relative);
        this.PixelShader = pixelShader;

        this.UpdateShaderValue(InputProperty);
        this.UpdateShaderValue(CenterPointProperty);
        this.UpdateShaderValue(PrimaryColorProperty);
        this.UpdateShaderValue(SecondaryColorProperty);
    }
    public Brush Input {
        get {
            return ((Brush)(this.GetValue(InputProperty)));
        }
        set {
            this.SetValue(InputProperty, value);
        }
    }
    /// <summary>The center of the gradient. </summary>
    public Point CenterPoint {
        get {
            return ((Point)(this.GetValue(CenterPointProperty)));
        }
        set {
            this.SetValue(CenterPointProperty, value);
        }
    }
    /// <summary>The primary color of the gradient. </summary>
    public Color PrimaryColor {
        get {
            return ((Color)(this.GetValue(PrimaryColorProperty)));
        }
        set {
            this.SetValue(PrimaryColorProperty, value);
        }
    }
    /// <summary>The secondary color of the gradient. </summary>
    public Color SecondaryColor {
        get {
            return ((Color)(this.GetValue(SecondaryColorProperty)));
        }
        set {
            this.SetValue(SecondaryColorProperty, value);
        }
    }
}

像这样在Xaml中使用它,该效果将所有非透明像素替换为渐变,因此形状必须具有颜色,可以是任何颜色:

Use it in Xaml like this, the effect replaces all non transparent pixels with the gradient, hence the shape must have a color, any color:

<Ellipse x:Name="ShaderEllipse" Fill="Transparent" Stroke="Blue" StrokeThickness="15">
    <Ellipse.Effect>
        <effects:AngularGradientEffect PrimaryColor="Red" 
                                       SecondaryColor="Transparent"/>
    </Ellipse.Effect>
</Ellipse>

输出为:

将其添加到此库

这篇关于WPF中的AngleGradient的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-16 05:17