在 WPF 中绘制到 DrawingContext 时如何应用投影效果?
Posted
技术标签:
【中文标题】在 WPF 中绘制到 DrawingContext 时如何应用投影效果?【英文标题】:How to apply a drop shadow effect when drawing to a DrawingContext in WPF? 【发布时间】:2012-01-29 03:45:28 【问题描述】:我正在向DrawingContext
绘图,我想对绘图的一部分应用投影效果。目前我在DrawingGroup
中创建相关部分并应用BitmapEffect
,但这没有效果:
var layer = new DrawingGroup();
using (var lcontext = layer.Open())
// draw stuff in lcontext
layer.BitmapEffect = new DropShadowBitmapEffect Color = Colors.Black, ShadowDepth = 3, Opacity = 0.5 ;
context.DrawDrawing(layer);
这会正确地绘制layer
内的所有内容,但没有投影效果。
我做错了什么/我还能如何将阴影应用到 DrawingContext 中的一堆图元?
【问题讨论】:
【参考方案1】:BitmapEffect
是 .NET 3.5 之前的旧属性(他们使用 CPU 渲染效果)。 4.0 中的属性has no effect。
在 4.0 中,您应该使用 Effect
属性,它使用像素着色器。
DrawingGroup
但是似乎没有效果属性 - 听起来您可能需要set the effect on the parent UI element instead。
【讨论】:
嗯...我没有父 UI 元素;这个DrawingGroup
直接呈现为RenderTargetBitmap
。奇怪的是,我必须使用 UI 元素进行纯渲染,嗯?...
我不认为这很奇怪 - 在内存中创建位图时,它还没有发送到 GPU,因此 GPU 无法运行像素着色器。旧的BitmapEffects
没有使用像素着色器,它们在 CPU 上运行,这就是它们在这种情况下工作的原因。不过大多数时候 BitmapEffects 太慢了,这就是它们被淘汰的原因。
在这种情况下,您可能可以使用绘图组填充一个 Rectangle,然后将 Rectangle 渲染到 RenderTargetBitmap(不要忘记先调整元素的大小)——这应该(我认为)调用 GPU调用你的着色器。【参考方案2】:
如果您在 .NET Framework 3.5 SP1 或更高版本上运行,则应使用 UIElement.Effect 或 Visual.VisualEffect(这是受保护的,因此您需要从它派生),并使用 System.Windows.Media.Effects.DropShadowEffect 的实例.
【讨论】:
ADrawingGroup
既不是Visual
也不是UIElement
,那么我应该在哪里应用这个效果呢?
我将图像和图元之类的东西绘制到我的DrawingGroup
中(使用我在问题中引用的代码)。然后我使用DrawDrawing
渲染它。我也想做同样的事情,但要让 DrawingGroup
中的所有内容都投下阴影。
根据我的经验,DrawingContext
是 GDI API 的完美替代品。似乎没有现成的阴影效果,这是可以理解的。您想更新或删除您的答案吗?就目前而言,它不适用/具有误导性。
让我给你我的角度 - 我从 FrameworkElement 继承了 SomeControl,并覆盖了 OnRender。 UIElement.Effect 还不够好——它把效果放在整个元素上,而贬低的 PushEffect 只能把效果放在几行 drawingContext.DrawXXX 上,让我不能一次把效果放在整个元素上。 WPF4 => 控制比 WPF3 少?
@SimonMourier 感谢您的帮助。 FWIW,我认为删除答案不需要任何费用。以上是关于在 WPF 中绘制到 DrawingContext 时如何应用投影效果?的主要内容,如果未能解决你的问题,请参考以下文章