【问题标题】:How to imitate OuterGlowBitmapEffect using WPF effects?如何使用 WPF 效果模仿 OuterGlowBitmapEffect?
【发布时间】:2021-09-16 09:14:59
【问题描述】:

我尝试使用 DropShadowEffect,但是当你增加 BlurRadius 时,它的“发光”强度会减弱。我想要像下图那样有强烈的外发光。

如果我将相同的效果叠加十几次,我就能得到这个,但在此之后性能下降。这可以使用具有单一效果的 WPF 吗?

【问题讨论】:

  • 如果您有这样的非常具体的要求,那么我建议您有两种选择。 1)写自己的效果。然后它会做任何你想做的事。 2) 使用画笔 - 如果您可以构建一次,捕获并重新用作图片,那么构建过程的成本就无关紧要了。
  • 以编程方式构建此类图像的一种方法是使用 writeablebitmap。这是相当快的。我在我们的游戏中为地图背景构建了一个 1155 x 805 的分辨率,它需要 20 多毫秒。您需要比高斯更快的更简单算法来计算每个像素的颜色强度。如果你然后模糊图像,那不需要太精确。
  • 一个简单的解决方案是用 Image 控件包围目标控件,该控件指向具有透明度的阴影 .PNG 文件(类似于 i.imgur.com/T7uNORE.png),您可以将其拉伸到控件大小。好处是您可以精心制作您想要的图像。

标签: c# .net wpf effects glow


【解决方案1】:

根据您希望模糊半径的大小以及结果需要的平滑程度,您可以堆叠不同的效果,例如渐变停止,而不是重复堆叠相同的效果。


正如您所指出的,DropShadowEffect 的强度随着BlurRadius 的增加而变弱。

<TextBox Text="DropShadowEffect">
    <TextBox.Effect>
        <DropShadowEffect BlurRadius="50"
                          ShadowDepth="0" 
                          Color="Blue" 
                          Opacity="1"/>
    </TextBox.Effect>
</TextBox>

此外,将效果直接应用于TextBox impacts the rendering quality of the text。链接问题的建议解决方案(在Window 上设置TextOptions.TextFormattingMode="Display")也具有布局含义。相反,您可以在元素后面绘制 RectangleBlurEffect

<Rectangle Fill="Blue"
           Height={Binding ElementName=MyTextBox, Path=ActualHeight}"
           Width={Binding ElementName=MyTextBox, Path=ActualWidth}">
    <Rectangle.Effect>
        <BlurEffect Radius="50"/>
    </Rectangle.Effect>
</Rectangle>
<TextBox x:Name="MyTextBox" Text="Rectangle with BlurEffect"/>

然后,您可以为每个渐变色标添加额外的Rectangle。这里有两个:一个在50 定义模糊的整体大小,另一个在30 加强控件周围的光晕。

<Rectangle Fill="Blue"
           Height={Binding ElementName=MyTextBox, Path=ActualHeight}"
           Width={Binding ElementName=MyTextBox, Path=ActualWidth}">
    <Rectangle.Effect>
        <BlurEffect Radius="50"/>
    </Rectangle.Effect>
</Rectangle>
<Rectangle Fill="Blue"
           Height={Binding ElementName=MyTextBox, Path=ActualHeight}"
           Width={Binding ElementName=MyTextBox, Path=ActualWidth}">
    <Rectangle.Effect>
        <BlurEffect Radius="30"/>
    </Rectangle.Effect>
</Rectangle>
<TextBox x:Name="MyTextBox" Text="Two Rectangles with BlurEffect"/>

您询问了TextBox 角落周围的感知锐度,我必须承认我没有一个好的解决方案。我最初考虑使用 Border 而不是 Rectangle 来圆化您的控件背后的模糊元素的角落,但老实说,我看不出有什么不同。

<!-- Remove the CornerRadius property for square corners. -->
<Border CornerRadius="10" Background="Blue">
    <Border.Effect>
        <BlurEffect Radius="50"/>
    </Border.Effect>
</Border>
<Border CornerRadius="10" Background="Blue">
    <Border.Effect>
        <BlurEffect Radius="30"/>
    </Border.Effect>
</Border>

当然,您总是可以使背景对象大于您的控件。在这里,它们位于Grid 的同一个单元格中,但Border 有额外的空间来增长,因为TextBox 有一个Margin。较小的上/下边距和较大的左/右边距意味着控件周围的发光会更加均匀。

<!-- These items should be in the same cell of a Grid -->
<Border CornerRadius="10" Background="Blue">
    <Border.Effect>
        <BlurEffect Radius="50"/>
    </Border.Effect>
</Border>
<Border CornerRadius="10" Background="Blue">
    <Border.Effect>
        <BlurEffect Radius="30"/>
    </Border.Effect>
</Border>
<TextBox Text="TextBox has an 8px, 4px margin" Margin="8 4"/>

【讨论】:

  • 非常感谢。矩形的一件事是你可以注意到角落看起来很锋利,不像 OP 中的发光效果那样圆。有没有办法解决这个问题?基本上是在控件周围产生均匀的圆形光晕。
  • 我不认为有一个好的解决方案,因为BlurEffect 将近似椭圆,除非您的控件接近正方形。我添加了一个关于使用不同大小的背景对象可能适合您的需要的部分。
猜你喜欢
  • 1970-01-01
  • 2021-04-04
  • 2023-03-28
  • 2015-03-30
  • 2012-02-01
  • 2011-02-14
  • 1970-01-01
  • 1970-01-01
  • 2013-07-27
相关资源
最近更新 更多