我试图使用WPF WriteableBitmap类来允许我的应用程序将不透明蒙版应用于图像。
基本上我有一个蓝色矩形作为图像,另一个100%透明绿色矩形图像位于蓝色矩形顶部。
当用户将鼠标移到绿色(透明)图像上时,我想应用不透明蒙版(可能使用简单的椭圆),使其看起来像是发出绿光。
我故意不这样做是XAML和标准的WPF效果,因为我真的需要它是超级高效的,我最终会用更高级的blob换掉椭圆......
有什么想法吗?
谢谢!
答案 0 :(得分:2)
对不起,我不太明白你的意图。也许如果我能看到图像,我可以从头开始正确回答,但这是我的第一个也许错误的答案。
如果你说超高性能,你可能想看看像素着色器。它们由 G PU处理,由WPF以自定义效果的形式支持,并且易于实现。您也可以将着色器应用于播放视频,而使用WritableBitmap则很难。
要编写像素着色器,您需要使用来自DirectX SDK和Shazzam tool的FX编译器(fxc.exe) - Walt Ritscher的WYSIWYG WPF Shaders编译器。
当你同时获得它们时,请继续尝试以下HLSL代码
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#效果:
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的更多信息:
希望这会有所帮助:)