我在自定义FrameworkElement的OnRender方法中绘制图像。我想画出这张照片的影子。我需要在代码中执行此操作,并且我不想使用DropShadowBitmapEffect,因为它已过时。我怎样才能做到这一点?
public class MyDrawingView : FrameworkElement
{
protected override void OnRender(System.Windows.Media.DrawingContext dc)
{
drawImagesOnDrawingContext(dc);
}
public RenderTargetBitmap getBitmap()
{
DrawingVisual dv = new DrawingVisual();
using (DrawingContext dcMine = dv.RenderOpen())
{
drawImagesOnDrawingContext(dcMine);
dcMine.Close();
}
RenderTargetBitmap rtb = new RenderTargetBitmap(200, 200, 96, 96, PixelFormats.Pbgra32);
rtb.Render(dv);
return rtb;
}
private void drawImagesOnDrawingContext(System.Windows.Media.DrawingContext dc)
{
//how to draw shadow on bi?
BitmapImage bi = new BitmapImage(new Uri(@"D:\mytemp\img1.jpg"));
dc.DrawImage(bi, new Rect(50, 50, 100, 100));
//how to draw shadow on bi1
BitmapImage bi1 = new BitmapImage(new Uri(@"D:\mytemp\img2.jpg"));
dc.DrawImage(bi1, new Rect(30, 30, 100, 100));
}
}
请注意,下面SvenG建议的解决方案,为底层元素添加效果,对我来说不起作用,因为它给整个元素带来了阴影,而不是我绘制的单个图像。例如,如果我有两个重叠的DrawImage,建议的解决方案将考虑整体绘制阴影。上部图像的阴影不会在下部图像上绘制。
此外,我想使用getBitmap函数创建一个位图,如上所示,以使用阴影导出绘制的图像。
答案 0 :(得分:4)
在PushEffect()
上有一个旧的DrawingContext
调用可以完成你所需的操作,但是像BitmapEffect一样,这已经过时了。
BitmapEffect
的替换是Effect
类。有一个名为DropShadowEffect
的子类正是你所追求的,但不幸的是,正如SvenG所说,这不能直接应用于位图。
支持应用效果的最低级别元素是DrawingVisual
类。这不是太糟糕,因为DrawingVisual
是一个非常轻量级的类。没有布局开销。您最好的选择是在自己的DrawingVisual
中创建每个位图,并将视觉的Effect
属性设置为DropShadowEffect
。显然,如果你有数千个位图,它可能不是一个可行的解决方案。
所有这些都可以在代码中完成,但不是OnRender()
,因为每个视觉都有自己的渲染上下文。但是,要正确渲染子DrawingVisuals,您需要告诉框架它们。
您需要覆盖自定义元素中的两个方法才能看到这些视觉效果:VisualChildrenCount
表示您有多少个孩子,而GetVisualChild()则将它们返回给系统。因此,您需要保留一组视觉效果。如果您想针对他们进行点击测试,也可以致电AddVisualChild()
和AddLogicalChild()
。
public class MyDrawingView : FrameworkElement
{
List<DrawingVisual> _visuals = new List<DrawingVisual>();
public MyDrawingView()
{
CreateVisuals();
}
//Gets a bitmap rendering of the visual and its children for saving as image file
public RenderTargetBitmap GetBitmap()
{
var rtb = new RenderTargetBitmap(200, 200, 96, 96, PixelFormats.Pbgra32);
rtb.Render(this);
return rtb;
}
protected override int VisualChildrenCount
{
get
{
return _visuals.Count;
}
}
protected override Visual GetVisualChild(int index)
{
return _visuals[index];
}
private void CreateVisuals()
{
CreateVisualForBitmap(@"D:\mytemp\img1.jpg", new Rect(50, 50, 100, 100));
CreateVisualForBitmap(@"D:\mytemp\img2.jpg", new Rect(30, 30, 100, 100));
}
private void CreateVisualForBitmap(string bitmapPath, Rect bounds)
{
var bitmap = new BitmapImage(new Uri(bitmapPath));
var visual = new DrawingVisual();
visual.Effect = new DropShadowEffect();
using (DrawingContext dc = visual.RenderOpen())
{
dc.DrawImage(bitmap, bounds);
}
_visuals.Add(visual);
AddVisualChild(visual);
AddLogicalChild(visual);
}
}
答案 1 :(得分:1)
将以下代码添加到OnRenderMethod:
....
dc.DrawImage(bi, new Rect(50, 50, 100, 100));
// Create DropShadow
DropShadowEffect effect = new DropShadowEffect();
effect = new DropShadowEffect();
effect.Color = Colors.Gray;
effect.Direction = 45;
this.Effect = effect;