使用不同大小的像素着色器采样器创建WPF效果

5
我想创建一个效果,使用较大的图像通过WPF效果和HLSL生成较小的图像。但似乎由于某种原因,WPF将所有输入图像调整为呈现大小,这不是我想要的,因为它会严重裁剪我的一张图片,并使我的最终图片看起来不太好。 我的设置如下:我有一个视频大小为2592x1944的图像,播放在MediaElement上。我在大小为800x600的边框(或其他元素)上应用我的效果,并将MediaElement绑定到效果上,以便能够将要渲染的表面(边框)和要从中渲染的源(MediaElement)都发送到像素着色器。但由于对源的大量裁剪,结果图像非常像素化。有人知道是否有办法让WPF不裁剪像素着色器样本吗?
我发现 Greg Schecter 的这篇博客文章有点像我想要的,但是方向相反: http://blogs.msdn.com/b/greg_schechter/archive/2008/09/27/a-more-useful-multi-input-effect.aspx 他缩小了一张图片,但我想把它变大。问题在于他使用了 ImageBrush,而我使用 UIElements,所以我不知道是否有办法在 VisualBrush 上实现他所做的事情。
1个回答

2
在WPF中的Visual中,如果您的图像源比渲染尺寸大,由于WPF PixelShader失去了质量,因此您将无法执行任何操作。如果您的图像源比渲染尺寸小,则可以使用PaddingTopPaddingBottomPaddingLeftPaddingRight。只有一种方法可以帮助您保存完整的质量:

使用ImageImageBrush并将Stretch设置为None。这样,您就可以将完整的图像(Textura)发送到PixelShader。您必须在自定义的ShaderEffect中拥有DependencyProperty

public static readonly DependencyProperty ViewAspectProperty = DependencyProperty.Register(nameof(ViewAspect), typeof(Point), typeof(CustomEffect), new UIPropertyMetadata(new Point(1D, 1D), PixelShaderConstantCallback(0)));

    public Point ViewAspect
    {
        get => (Point)GetValue(ViewAspectProperty);
        set => SetValue(ViewAspectProperty, value);
    }

在Shader.fs文件中:
float2 ViewAspect : register(C0) = float2(1, 1);
sampler2D Input : register(s0);

struct VS_OUTPUT
{
    float4 Position : POSITION;
    float4 Color : COlOR;
    float2 UV : TEXCOORD;
};

float4 main(VS_OUTPUT input) : COlOR
{
  float2 uv = input.UV;  

    uv.x *= ViewAspect.x;
    uv.y *= ViewAspect.y;

    return tex2D(Input, uv);
}

当您的渲染控件大小发生变化时,您需要:
        ViewAspectX = ViewWidth > 0 ? FrameWidth / ViewWidth : 1;
        ViewAspectY = ViewHeight > 0 ? FrameHeight / ViewHeight : 1;

其中ViewWidthViewHeight是呈现FrameworkElement的尺寸,FrameWidthFrameHeight是源图像的尺寸。这样,您可以调整输入图像的大小而不会失去质量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接