WPF头像裁剪

本文介绍了在WPF中实现用户头像裁剪的需求,分析了两种不同的裁剪实现方式,包括截图框固定和背景图片固定大小的裁剪方法,并针对第二种方式进行了源码修改,确保裁剪框始终保持正方形。最后,详细说明了如何将修改后的代码应用到实际项目中,并处理裁剪后图片的缩放问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需求很常见,就是用户上传头像前进行固定大小的裁剪。
百度一番,找到几个差不多的,
其一 http://download.youkuaiyun.com/detail/tianhaosen/7159901,这个的实现方式是截图框大小固定不变,背景图可以通过鼠标拖动和鼠标滚轮缩放,经过测试,这个对图片的裁剪不是很准确,尤其是大图或者靠近图片边缘裁剪的时候会出现较大误差,然后我尝试调整了下截图位置的算法,但多少还是有偏差,无奈只好放弃,有兴趣的同学可以下下来研究研究。
其二 http://blog.youkuaiyun.com/jtl309/article/details/50651911,这个的实现方式是背景图片保持大小不变,裁剪框可以通过鼠标拖动进行缩放。于是尝试在这个的基础上进行调整:)
首先,裁剪框的拖动以及缩放作者已经做的很完善了,主要是利用了Thumb控件进行自定义。我的需求是裁剪框要是一个固定大小的正方形,所以我对作者的源码进行了修改。源码中作者是在DragHelperBase.cs中对矩形框的大小进行实时计算,其中有4个ResizeFrom**方法,我在这4个方法的入参中均加入了宽高(out double HeightNew,out double WidthNew),并且在方法的最后一行赋值高和宽相等,这样就保证了裁剪框始终是正方形,另外,作者的这个框框拖动的时候能把框拖到大边框以外,是个小bug,我这边在每次拖动之后都跟Parent.ActualWidth比较一下。ok,算法代码修改完毕,下面就是对样式代码进行了一些调整,这个各位同学根据自己需求改动即可。
主要修改了DragHelperBase.cs代码:

   #region ResizeElement
        private Rect ResizeElement(CustomThumb HitedThumb, double HorizontalChange, double VerticalChange)
        {
            #region Get Old Value

            if (HitedThumb == null) return Rect.Empty;


            Rect TargetActualBound = GetTargetActualBound();

            double TopOld    = CorrectDoubleValue(TargetActualBound.Y);
            double LeftOld   = CorrectDoubleValue(TargetActualBound.X);
            double WidthOld  = CorrectDoubleValue(TargetActualBound.Width);
            double HeightOld = CorrectDoubleValue(TargetActualBound.Height);

            double TopNew    = TopOld;
            double LeftNew   = LeftOld;
            double WidthNew  = WidthOld;
            double HeightNew = HeightOld;

            #endregion

            if (HitedThumb.DragDirection == DragDirection.TopLeft
                || HitedThumb.DragDirection == DragDirection.MiddleLeft
                || HitedThumb.DragDirection == DragDirection.BottomLeft)
            {
                ResizeFromLeft(DragHelperParent, LeftOld, WidthOld, TopOld, HeightOld, HorizontalChange, out LeftNew, out WidthNew, out HeightNew);
            }

            if (HitedThumb.DragDirection == DragDirection.TopLeft
                || HitedThumb.DragDirection == DragDirection.TopCenter
                || HitedThumb.DragDirection == DragDirection.TopRight)
            {
                ResizeFromTop(DragHelperParent, LeftOld, WidthOld, TopOld, HeightOld, VerticalChange, out TopNew, out HeightNew, out WidthNew);
            }

            if (HitedThumb.DragDirection == DragDirection.TopRight
                || HitedThumb.DragDirection == DragDirection.MiddleRight
                || HitedThumb.DragDirection == DragDirection.BottomRight)
            {
                ResizeFromRight(DragHelperParent, LeftOld, WidthOld,TopOld,HeightOld, HorizontalChange, out WidthNew, out HeightNew);
            }

            if (HitedThumb.DragDirection == DragDirection.BottomLeft
                || HitedThumb.DragDirection == DragDirection.BottomCenter
                || HitedThumb.DragDirection == DragDirection.BottomRight)
            {
                ResizeFromBottom(DragHelperParent, LeftOld, WidthOld, TopOld, HeightOld, VerticalChange, out HeightNew, out WidthNew);
            }

            WidthNew = WidthNew < 0 ? 0 : WidthNew;
            HeightNew = HeightNew < 0 ? 0 : HeightNew;

            this.Width = WidthNew;
            this.Height = HeightNew;
            Canvas.SetTop(this, TopNew);
            Canvas.SetLeft(this, LeftN
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值