zoukankan      html  css  js  c++  java
  • 2018-7-15-WPF-在-DrawingContext-的-push-如何使用

    title author date CreateTime categories
    WPF 在 DrawingContext 的 push 如何使用
    lindexi
    2018-7-15 15:51:0 +0800
    2018-07-15 15:26:42 +0800
    WPF

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

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

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

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

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

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

            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 画出来

            protected override void OnRender(DrawingContext drawingContext)
            {
                drawingContext.DrawDrawing(DrawingVisual.Drawing);
                base.OnRender(drawingContext);
            }

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

    如对 DrawingVisual 进行变换的代码

            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 就会叠加不透明度,如使用下面代码

                drawingContext.PushOpacity(0.3);
                drawingContext.PushOpacity(0.3);
    
    
                drawingContext.DrawDrawing(DrawingVisual.Drawing);

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

                drawingContext.PushOpacity(0.09);
    
                drawingContext.DrawDrawing(DrawingVisual.Drawing);

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

  • 相关阅读:
    PHP与CI学习笔记
    The Sum of the k-th Powers(Educational Codeforces Round 7F+拉格朗日插值法)
    Nastya Hasn't Written a Legend(Codeforces Round #546 (Div. 2)E+线段树)
    Please, another Queries on Array?(Codeforces Round #538 (Div. 2)F+线段树+欧拉函数+bitset)
    Gorgeous Sequence(HDU5360+线段树)
    Subsequence(HDU3530+单调队列)
    Qualification Rounds(Codeforces Round #438 by Sberbank and Barcelona Bootcamp (Div. 1 + Div. 2 combined)+状态压缩)
    Xenia and Weights(Codeforces Round #197 (Div. 2)+DP)
    字节跳动-文远知行杯”广东工业大学第十四届程序设计竞赛
    线段树优化建边
  • 原文地址:https://www.cnblogs.com/lindexi/p/12086197.html
Copyright © 2011-2022 走看看