WPF 在 DrawingContext 的 push 如何使用

2022-08-04 15:22:33 浏览数 (1)

本文告诉大家如何使用 DrawingContext 变换,修改画出的内容。

如果在一个 DrawingContext 画出一个 DrawingVisual ,如何修改这个 DrawingVisual 的大小,对他进行变换?

简单的方法就是使用 PushTransform 方法,那么如何使用这个方法就是本文要告诉大家的。

先写一个简单的 OnRender ,创建一个类 GearcawralSarBule 继承 FrameworkElement 就可以重写 OnRender 方法,为了让WPF调用 OnRender 方法就需要把 GearcawralSarBule 加入视觉树,最简单加入视觉树的方法就是把他添加到 Grid,下面就是 GearcawralSarBule 类代码和在 xaml 添加他到 Grid 显示

代码语言:javascript复制
    public class GearcawralSarBule : FrameworkElement
    {
        /// <inheritdoc />
        protected override void OnRender(DrawingContext drawingContext)
        {
            base.OnRender(drawingContext);
        }
    }
代码语言:javascript复制
        <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
            <local:GearcawralSarBule></local:GearcawralSarBule>
        </Grid>

现在运行可以看到界面没有内容,下面来使用一个已有的图片画出来。

代码语言:javascript复制
        public GearcawralSarBule()
        {
            DrawingVisual = new DrawingVisual();
            using (var drawingContext = DrawingVisual.RenderOpen())
            {
                // 本来是想写文字 lindexi 的,但是最后还是画星
                drawingContext.DrawGeometry(Brushes.Black, null, Geometry.Parse("m25,1 6,17h18l-14,11 5,17-15-10-15,10 5-17-14-11h18z"));
            }

            DrawingVisual.CacheMode = new BitmapCache();
        }

        private DrawingVisual DrawingVisual { get; set; }

上面代码使用 Geometry.Parse 转换一个图形,大家先猜一下是什么图形。

下面来把上面的 DrawingVisual 画出来

代码语言:javascript复制
        protected override void OnRender(DrawingContext drawingContext)
        {
            drawingContext.DrawDrawing(DrawingVisual.Drawing);
            base.OnRender(drawingContext);
        }

那么现在的问题是如何缩放这个画出来的 DrawingVisual ,实际上方法很简单,就是通过 drawingContext 的 push 方法。如果有玩过 ps 就知道,在 ps 有图层,使用 DrawingContext 的 push 方法就是创建一个图层,而且做的变换都是对这个图层做变换,在使用 push 创建图层之后需要使用 pop 把图层画进去。

如对 DrawingVisual 进行变换的代码

代码语言:javascript复制
        protected override void OnRender(DrawingContext drawingContext)
        {
            drawingContext.PushTransform(new ScaleTransform()
            {
                ScaleX = 2,
                ScaleY = 2,
            });
            drawingContext.DrawDrawing(DrawingVisual.Drawing);
            drawingContext.Pop();
            base.OnRender(drawingContext);
        }

这时就可以对 DrawingVisual 放大,因为 Transform 可以进行移动、旋转,这里的代码就不告诉大家了

注意使用了 push 需要在画完使用 pop ,不然会出现下面继续对 DrawingVisual 进行画的时候就会发现还是在原先的图层

除了 PushTransform 方法还有很多 push 方法,如 PushClip ,调用这个方法可以裁剪传入的范围。如 PushOpacity 可以设置接下来画的图片的不透明度,如果多次调用 PushOpacity 没有调用 Pop 就会叠加不透明度,如使用下面代码

代码语言:javascript复制
            drawingContext.PushOpacity(0.3);
            drawingContext.PushOpacity(0.3);


            drawingContext.DrawDrawing(DrawingVisual.Drawing);

和使用下面代码画出来的图形不透明度相同

代码语言:javascript复制
            drawingContext.PushOpacity(0.09);

            drawingContext.DrawDrawing(DrawingVisual.Drawing);

还有一个 PushGuidelineSet 参见:WPF:基于物理像素的图形绘制 - Aaron Lu - 博客园

0 人点赞