wpf放大镜

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ControlStudy
{
    /// <summary>
    /// Magnifier.xaml 的交互逻辑
    /// </summary>
    public partial class Magnifier : UserControl
    {
        public Magnifier()
        {
            InitializeComponent();
        }

        private double Zoom = 1.0d;

        public bool ImgVisZoom
        {
            get { return (bool)GetValue(ImgVisZoomProperty); }
            set { SetValue(ImgVisZoomProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ImgVisZoom.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ImgVisZoomProperty =
            DependencyProperty.Register("ImgVisZoom", typeof(bool), typeof(Magnifier), new PropertyMetadata(false));

        public BitmapSource ImgSource
        {
            get { return (BitmapSource)GetValue(ImgSourceProperty); }
            set { SetValue(ImgSourceProperty, value); }
        }

        // Using a DependencyProperty as the backing store for bitmapSource.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ImgSourceProperty =
            DependencyProperty.Register("ImgSource", typeof(BitmapSource), typeof(Magnifier));

        private void Ellipse_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            Zoom = 1.0f;
            ImgVisZoom = false;
        }

        private void Grid_MouseMove(object sender, MouseEventArgs e)
        {
            if (!ImgVisZoom) return;
            double Zwidth = ImgSource.Width / ActualWidth;
            double Zheight = ImgSource.Height / ActualHeight;
            System.Windows.Point point = Mouse.GetPosition(gridMagnifier);
            ellipse.Margin = new Thickness
            {
                Left = point.X - ellipse.Width / 2,
                Top = point.Y - ellipse.Height / 2
            };
            double CenterX = point.X * Zwidth;
            double CenterY = point.Y * Zheight;
            double CutWidth = ellipse.Width * Zwidth / Zoom;
            double CutHeight = ellipse.Height * Zheight / Zoom;
            Int32Rect CutRect = new Int32Rect
            {
                Width = (int)CutWidth,
                Height = (int)CutHeight,
                X = (int)(CenterX - CutWidth / 2),
                Y = (int)(CenterY - CutHeight / 2)
            };
            ImageZoom.ImageSource = ImgClipRect(CutRect);
        }

        private void Ellipse_MouseWheel(object sender, MouseWheelEventArgs e)
        {
            Zoom = Math.Round(Zoom, 2);
            if (e.Delta > 0 && Zoom >= 1)
            {
                Zoom += 0.2;
            }
            if (e.Delta < 0 && Zoom >= 1.1)
            {
                Zoom -= 0.2;
            }
            Grid_MouseMove(null, null);
        }

        /// <summary>
        /// 裁剪图片
        /// </summary>
        /// <param name="CutRect">裁剪范围</param> 
        /// <returns></returns>
        public BitmapSource ImgClipRect(Int32Rect CutRect)
        {
            List<byte> ListBytes = new List<byte>();
            //byte[] bufOrignal = new byte[(int)(ImgSource.Width * ImgSource.Height)];
            Int32Rect rect = new Int32Rect
            {
                X = 0,
                Y = 0,
                Height = (int)ImgSource.Height,
                Width = (int)ImgSource.Width,
            };
            var stride = ImgSource.Format.BitsPerPixel * rect.Width / 8;//计算Stride
            byte[] bufOrignal = new byte[rect.Height * stride];
            ImgSource.CopyPixels(rect, bufOrignal, stride, 0); //像素值拷贝

            int cutRectX_Temp = ImgSource.Format.BitsPerPixel * CutRect.X / 8;
            int cutRectWidth_Temp = ImgSource.Format.BitsPerPixel * CutRect.Width / 8;

            for (int row = CutRect.Y; row < CutRect.Y + CutRect.Height; row++)
            {
                //for (int col = CutRect.X; col < CutRect.X + CutRect.Width; col++)
                for (int col = cutRectX_Temp; col < cutRectX_Temp + cutRectWidth_Temp; col++)
                {
                    if (row < 0 || row >= ImgSource.Height || col < 0 || col >= stride)
                    //(row < 0 || row >= ImgSource.Height || col < 0 || col >= ImgSource.Width)
                    {
                        ListBytes.Add(0);
                    }
                    else
                    {
                        //int Index = (int)(row * ImgSource.Width + col);
                        int Index = (int)(row * stride + col);
                        ListBytes.Add(bufOrignal[Index]);
                    }
                }
            }
            IntPtr pData = Marshal.AllocHGlobal(ListBytes.Count);
            BitmapSource source = null;
            try
            {
                Marshal.Copy(ListBytes.ToArray(), 0, pData, ListBytes.Count);
                string strTImgType = ImgSource.Format.ToString();
                if (strTImgType.Contains("Rgb24"))
                {
                    source = BitmapSource.Create(CutRect.Width, CutRect.Height, 0, 0, PixelFormats.Rgb24, null, pData, cutRectWidth_Temp * CutRect.Height, cutRectWidth_Temp); //bgr24 血流图像
                }
                else
                {
                    source = BitmapSource.Create(CutRect.Width, CutRect.Height, 96, 96, PixelFormats.Gray8, BitmapPalettes.Gray256, pData, CutRect.Width * CutRect.Height, CutRect.Width); //gray8
                }
            }
            catch (Exception ex)
            {
            }
            finally
            {
                Marshal.FreeHGlobal(pData);
            }
            return source;
        }
    }
}
 

<UserControl x:Class="ControlStudy.Magnifier"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:ControlStudy"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Button Height="30" Width="50" VerticalAlignment="Top" HorizontalAlignment="Left"/>
        <Image Source="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=local:Magnifier},Path=ImgSource}" Stretch="Fill"/>
        <Grid x:Name="gridMagnifier" Background="Transparent">
            <Ellipse x:Name="ellipse" Width="200"  Height="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Width}" StrokeThickness="5" HorizontalAlignment="Left" VerticalAlignment="Top" MouseWheel="Ellipse_MouseWheel" MouseLeftButtonDown="Ellipse_MouseLeftButtonDown">
                <Ellipse.Stroke>
                    <LinearGradientBrush  EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#f4f7fb" Offset="0.25"/>
                        <GradientStop Color="#e9f0f7" Offset="0.375"/>
                        <GradientStop Color="#cedbe9" Offset="0.5"/>
                        <GradientStop Color="#aabfd4" Offset="0.6"/>
                        <GradientStop Color="#aabfd4" Offset="0.65"/>
                        <GradientStop Color="#9bb0c5" Offset="0.8"/>
                        <GradientStop Color="#8ea1b4" Offset="0.9"/>
                        <GradientStop Color="#6f7f90" Offset="1.0"/>
                    </LinearGradientBrush>
                </Ellipse.Stroke>
                <Ellipse.Fill>
                    <ImageBrush x:Name="ImageZoom" RenderOptions.BitmapScalingMode="Fant" ></ImageBrush>
                </Ellipse.Fill>
            </Ellipse>
        </Grid>
    </Grid>
</UserControl>
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值