首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WPF WriteableBitmap和效果

WPF WriteableBitmap和效果
EN

Stack Overflow用户
提问于 2009-10-28 07:26:59
回答 1查看 2.1K关注 0票数 0

我正在尝试使用WPF WriteableBitmap类来允许我的应用程序将不透明蒙版应用于图像。

基本上我有一个蓝色矩形作为图像,另一个100%透明的绿色矩形图像覆盖在蓝色的上面。

当用户将鼠标移动到绿色(透明)图像上时,我希望应用不透明蒙版(可能使用一个简单的椭圆),以便它看起来像是正在发出绿色光芒。

我故意不这样做,这是XAML和标准的WPF效果,因为我真的需要它是超级性能,我最终会换出一个更高级的斑点椭圆…

有什么想法吗?

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2009-10-28 08:22:42

对不起,我不太明白你的意图。也许如果我能看到这张图片,我就能从一开始就回答正确,但这是我的第一个可能是错误的答案。

如果你说超级性能,你可能想看看像素着色器。它们由GPU处理,并由WPF以自定义效果的形式提供支持,并且易于实现。您还可以将着色器应用于播放视频,而使用WritableBitmap很难做到这一点。

要编写像素着色器,需要有来自DirectX SDK的FX编译器(fxc.exe)和由Walt Ritscher编写的Shazzam tool - WYSIWYG WPF Shaders编译器。

当您获得这两个代码时,请继续尝试以下HLSL代码

代码语言:javascript
复制
float X : register(C0); // Mouse cursor X position
float Y : register(C1); // Mouse cursor Y position
float4 Color : register(C2); // Mask color
float R : register(C3); // Sensitive circle radius.

sampler2D implicitInputSampler : register(S0);


float4 main(float2 uv : TEXCOORD) : COLOR
{
    float4 finalColor = tex2D(implicitInputSampler, uv);
    if ( (uv.x - X) * (uv.x - X) + (uv.y - Y) * (uv.y - Y) < R*R)
    {
        finalColor = Color; // Blend/Change/Mask it as you wish here.
    }
    return finalColor;
}

这将为您提供以下C#效果:

代码语言:javascript
复制
namespace Shazzam.Shaders {
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Media.Effects;


    public class AutoGenShaderEffect : ShaderEffect {

        public static DependencyProperty InputProperty = ShaderEffect.RegisterPixelShaderSamplerProperty("Input", typeof(AutoGenShaderEffect), 0);

        public static DependencyProperty XProperty = DependencyProperty.Register("X", typeof(double), typeof(AutoGenShaderEffect), new System.Windows.UIPropertyMetadata(new double(), PixelShaderConstantCallback(0)));

        public static DependencyProperty YProperty = DependencyProperty.Register("Y", typeof(double), typeof(AutoGenShaderEffect), new System.Windows.UIPropertyMetadata(new double(), PixelShaderConstantCallback(1)));

        public static DependencyProperty ColorProperty = DependencyProperty.Register("Color", typeof(System.Windows.Media.Color), typeof(AutoGenShaderEffect), new System.Windows.UIPropertyMetadata(new System.Windows.Media.Color(), PixelShaderConstantCallback(2)));

        public static DependencyProperty RProperty = DependencyProperty.Register("R", typeof(double), typeof(AutoGenShaderEffect), new System.Windows.UIPropertyMetadata(new double(), PixelShaderConstantCallback(3)));

        public AutoGenShaderEffect(PixelShader shader) {
            // Note: for your project you must decide how to use the generated ShaderEffect class (Choose A or B below).
            // A: Comment out the following line if you are not passing in the shader and remove the shader parameter from the constructor

            PixelShader = shader;

            // B: Uncomment the following two lines - which load the *.ps file
            // Uri u = new Uri(@"pack://application:,,,/glow.ps");
            // PixelShader = new PixelShader() { UriSource = u };

            // Must initialize each DependencyProperty that's affliated with a shader register
            // Ensures the shader initializes to the proper default value.
            this.UpdateShaderValue(InputProperty);
            this.UpdateShaderValue(XProperty);
            this.UpdateShaderValue(YProperty);
            this.UpdateShaderValue(ColorProperty);
            this.UpdateShaderValue(RProperty);
        }

        public virtual System.Windows.Media.Brush Input {
            get {
                return ((System.Windows.Media.Brush)(GetValue(InputProperty)));
            }
            set {
                SetValue(InputProperty, value);
            }
        }

        public virtual double X {
            get {
                return ((double)(GetValue(XProperty)));
            }
            set {
                SetValue(XProperty, value);
            }
        }

        public virtual double Y {
            get {
                return ((double)(GetValue(YProperty)));
            }
            set {
                SetValue(YProperty, value);
            }
        }

        public virtual System.Windows.Media.Color Color {
            get {
                return ((System.Windows.Media.Color)(GetValue(ColorProperty)));
            }
            set {
                SetValue(ColorProperty, value);
            }
        }

        public virtual double R {
            get {
                return ((double)(GetValue(RProperty)));
            }
            set {
                SetValue(RProperty, value);
            }
        }
    }
}

现在,您可以跟踪鼠标位置,并设置相应的效果属性以触发更改。这里需要注意的一点是:在HLSL代码中,X和Y的范围是从0到1。因此,在将它们传递给着色器之前,您必须将实际坐标转换为百分比。

有关像素着色器和WPF的更多信息:

希望这能有所帮助:)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1634295

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档