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>