专栏首页林德熙的博客WPF 通过 DrawingContext DrawImage 绘制图片 裁剪图片

WPF 通过 DrawingContext DrawImage 绘制图片 裁剪图片

本文告诉大家如何通过 DrawingContext 绘制图片,同时指定绘制图片在画布的某个区域和绘制出来的图片大小,如何裁剪图片

在 WPF 中可以使用 DrawingVisual 进行底层的绘制,底层的绘制的效率是比较高的,但是因为 WPF 的界面需要的是 UIElement 如果想要添加 DrawingVisual 还需要写一个帮助类

    public class Element : UIElement
    {
        /// <inheritdoc />
        public Element()
        {
            ContainerVisual = new ContainerVisual();
            AddVisualChild(ContainerVisual);
        }

        /// <inheritdoc />
        protected override Visual GetVisualChild(int index)
        {
            return ContainerVisual;
        }

        public ContainerVisual ContainerVisual { get; }

        /// <inheritdoc />
        protected override int VisualChildrenCount => 1;
    }

将这个 Element 加入到界面

    <Grid>
        <local:Element x:Name="Element"></local:Element>
    </Grid>

然后在构造函数添加一张图片,这时需要拖动一张图片进入解决方案

        public MainWindow()
        {
            InitializeComponent();

            var bitmapImage = new BitmapImage(new Uri("pack://application:,,,/1.jpg"));
            var drawingVisual = new DrawingVisual();
            using (DrawingContext dc = drawingVisual.RenderOpen())
            {
                dc.DrawImage(bitmapImage, new Rect(100, 100, 50, 50));
            }

            Element.ContainerVisual.Children.Add(drawingVisual);
        }

现在可以看到图片在 100,100 的坐标画出,此时图片为被缩放到 50x50 也就是缩放画图片到指定的 Rect 上

裁剪图片

如果只是需要画出被裁剪的图片,可以使用 CroppedBitmap 进行裁剪

在 CroppedBitmap 的构造可以传入需要裁剪的图片和如何裁剪,裁剪是进行矩形的裁剪

如下面代码是裁剪矩形从图片的左上角 50x50 范围

                var croppedBitmap = new CroppedBitmap(bitmapImage, new Int32Rect(0, 0, 50, 50));

将两个图片同时画出来

        public MainWindow()
        {
            InitializeComponent();

            var bitmapImage = new BitmapImage(new Uri("pack://application:,,,/1.jpg"));
            var drawingVisual = new DrawingVisual();
            using (DrawingContext dc = drawingVisual.RenderOpen())
            {
                // 裁剪图片的 50x50 部分
                var croppedBitmap = new CroppedBitmap(bitmapImage, new Int32Rect(0, 0, 50, 50));
                dc.DrawImage(croppedBitmap, new Rect(10, 10, 50, 50));
                dc.DrawImage(bitmapImage, new Rect(100, 100, 500, 500));
            }

            Element.ContainerVisual.Children.Add(drawingVisual);
        }

需要需要裁剪圆形,可以依靠 PushClip 裁剪

下面代码裁剪一个圆形的范围,从圆心 30x30 开始裁剪半径为 20 的范围

                dc.PushClip(new EllipseGeometry(new Point(30, 30), 20, 20));

使用裁剪之后的图片

        public MainWindow()
        {
            InitializeComponent();

            var bitmapImage = new BitmapImage(new Uri("pack://application:,,,/1.jpg"));
            var drawingVisual = new DrawingVisual();
            using (DrawingContext dc = drawingVisual.RenderOpen())
            {
                dc.PushClip(new EllipseGeometry(new Point(30, 30), 20, 20));
                // 裁剪图片的 50x50 部分
                var croppedBitmap = new CroppedBitmap(bitmapImage, new Int32Rect(0, 0, 50, 50));
                dc.DrawImage(croppedBitmap, new Rect(10, 10, 50, 50));
                dc.Pop();

                dc.DrawImage(bitmapImage, new Rect(100, 100, 500, 500));
            }

            Element.ContainerVisual.Children.Add(drawingVisual);
        }

本文会经常更新,请阅读原文: https://lindexi.gitee.io/post/WPF-%E9%80%9A%E8%BF%87-DrawingContext-DrawImage-%E7%BB%98%E5%88%B6%E5%9B%BE%E7%89%87.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接: https://lindexi.gitee.io ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • WPF 文字描边

    在WPF如果需要写入描边需要使用 FormattedText 将文字转换为 Geometry 然后通过画出 Geometry 的边框和填充画出描边

    林德熙
  • win10 uwp 分治法

    算法涉及到了一个平面几何的知识。就是三角形p1p2p3的面积等于以下行列式的二分之一: % <![CDATA[ \begin{array}{cccc} | ...

    林德熙
  • win10 uwp 气泡 WPF 气泡

    假设尖头宽度 10 高度 5 ,那么可以看到第一个点是 (0,5) 第二个点是 (5,0) 第三个点是 (10,5)

    林德熙
  • rails -help

    rails new APP_PATH [选项] //APP_PATH项目名称

    不知雨
  • 【pytorch】改造mobilenet_v2进行multi-class classification(多标签分类)

    在图像分类领域,对象可能会存在多个属性的情况。例如,这些属性可以是类别,颜色,大小等。与通常的图像分类相反,此任务的输出将包含2个或更多属性。本文考虑的是多输出...

    绝命生
  • Flutter质感设计之模态底部面板

    模态底部面板是菜单或对话框的替代方案,可防止用户与其他控件进行互动,可以使用showModalBottomSheet函数创建和显示模态底部面板。

    砸漏
  • 这一次搞懂Spring事务注解的解析

    事务我们都知道是什么,而Spring事务就是在数据库之上利用AOP提供声明式事务和编程式事务帮助我们简化开发,解耦业务逻辑和系统逻辑。但是Spring事务原理是...

    夜勿语
  • 如何完成EXcel表格制作,这5个技巧轻松搞定

    很多人在接触到EXcel表格的时候,都会问EXcel表格制作到底怎么做呢?作为办公室一族,都会经常用到EXcel来统计报表和数据的,当遇到自己不会的操作时,就要...

    高效办公
  • 快速学习代码生成器-构造数据模型

    借助Freemarker机制可以方便的根据模板生成文件,同时也是组成代码生成器的核心部分。对于Freemarker而言,其强调 数据模型 + 模板 = 文件 的...

    cwl_java
  • python apscheduler 每两小时执行一次

    from datetime import datetime from apscheduler.schedulers.blocking import Block...

    用户5760343

扫码关注云+社区

领取腾讯云代金券