在XAML代码设计器中,添加canvas画布与圆形几何对象,利用VisualBrush笔刷来复制画面内容到指定容器:

<Canvas x:Name="CvsGlass" Width="106" Height="106"  HorizontalAlignment="Left" VerticalAlignment="Top"  MouseWheel="CvsGlass_MouseWheel" MouseDown="CvsGlass_MouseDown" MouseUp="CvsGlass_MouseUp" MouseMove="CvsGlass_MouseMove" MouseLeave="CvsGlass_MouseLeave">
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform/>
</TransformGroup>
</Canvas.RenderTransform>
<Canvas Name="magnifierCanvas">
<Ellipse Width="106" Height="106" >
<Ellipse.Fill>
<LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
<GradientStop Color="#FFD9D2D2" Offset="1"/>
<GradientStop Color="White"/>
<GradientStop Color="#FFDFDFDF" Offset="0.244"/>
<GradientStop Color="#FF777777" Offset="0.592"/>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
<Ellipse Width="100" Height="100" Canvas.Left="3" Canvas.Top="3" Fill="Black"/>
<Ellipse Width="100" Height="100" Name="magnifierEllipse" Canvas.Left="3" Canvas.Top="3">
<Ellipse.Fill>
<VisualBrush ViewboxUnits="Absolute" Viewbox="0,0,100,100" ViewportUnits="RelativeToBoundingBox" Viewport="0,0,1,1"/>
</Ellipse.Fill>
</Ellipse>
<TextBlock x:Name="TxtGlassScale" Foreground="Yellow" Visibility="Hidden" FontSize="14" Margin="110,40,0,55" FontFamily="Microsoft YaHei">
<TextBlock.Effect>
<DropShadowEffect/>
</TextBlock.Effect>
</TextBlock>
</Canvas>
</Canvas>

得到一个类似放大镜的界面效果:

其中,TxtGlassScale是显示放大镜倍数的文字控件;

VisualBrush是内容笔刷,看效果:

其中需要注意的是,放大镜应该是和Box平级,属于Cell的子控件,这样在图像平铺模式下则能兼容所有图像范围:

看效果:

参考代码:

    #region -----放大镜-----/// <summary>
/// 当前大小与vs设计器中的大小的比例
/// </summary>
public double ActualScaleVal = ; /// <summary>
/// 放大比例
/// </summary>
double glassScale = 2.0; /// <summary>
/// 放大镜视图范围宽度
/// </summary>
double glassWidth = ; /// <summary>
/// 放大镜视图范围高度
/// </summary>
double glassHeight = ; /// <summary>
/// 显示放大镜
/// </summary>
public void UseGlass()
{
if (CvsGlass.IsShow())
{
CvsGlass.Hide();
return;
} if (glassWidth == || glassHeight == )
{
//计算放大镜比例 100是放大镜的viewbox的大小
glassWidth = / glassScale;
glassHeight = / glassScale; }
TxtGlassScale.Foreground = shapeManager.shapeMeasureColor;
TxtGlassScale.FontSize = shapeManager.shapeMeasureFontSize;
SetGlassViewBox(ActualWidth, ActualHeight, new Point(), true);
CvsGlass.Show();
} /// <summary>
/// 关闭放大镜
/// </summary>
public void CloseGlass()
{
CvsGlass.Hide();
} //滚轮控制放比例
private void CvsGlass_MouseWheel(object sender, MouseWheelEventArgs e)
{
if (e.Delta > )
{
glassScale -= 0.05;
}
else
{
glassScale += 0.05;
} glassScale = glassScale < 0.1 ? 0.1 : glassScale;
glassScale = glassScale > ? : glassScale; glassWidth = / glassScale;
glassHeight = / glassScale; Point pos = e.MouseDevice.GetPosition(GridMain);
SetGlassViewBox(pos.X, pos.Y, new Point(), false, false);
TxtGlassScale.Text = ((glassScale * ActualScaleVal * ) * ).ToString("f1") + "%";
TxtGlassScale.Show(); } //是否按下放大镜鼠标
bool isGlassDown = false; //记录按下鼠标的位置
Point glassPoint = new Point(, ); //按下放大镜
private void CvsGlass_MouseDown(object sender, MouseButtonEventArgs e)
{
glassPoint.X = e.GetPosition(CvsGlass).X;
glassPoint.Y = e.GetPosition(CvsGlass).Y;
isGlassDown = true;
} //移动放大镜
private void CvsGlass_MouseMove(object sender, MouseEventArgs e)
{
if (isGlassDown)
{
//相对于 GridLine 获取鼠标的坐标
Point svMainPos = e.MouseDevice.GetPosition(ScrollCell); Point glassPos = e.MouseDevice.GetPosition(CvsGlass); SetGlassViewBox(glassPos.X, glassPos.Y, svMainPos, false); Mouse.Capture(CvsGlass);
}
} /// <summary>
/// 设置放大内容
/// </summary>
/// <param name="vbX">宽度参数</param>
/// <param name="vbY">高度参数</param>
/// <param name="svMainPos">相对于GridLine的坐标</param>
/// <param name="isInit">是否是初始化</param>
/// <param name="reLocation">是否重新定位坐标</param>
private void SetGlassViewBox(double vbX, double vbY, Point svMainPos, bool isInit = false, bool reLocation = true)
{
Rect viewBox = GlassVB.Viewbox;
double xoffset = viewBox.Width / 2.0;
double yoffset = viewBox.Height / 2.0;
if (isInit)
{
viewBox.X = (vbX - xoffset) / ;
viewBox.Y = (vbY - yoffset) / ;
CvsGlass.Margin = new Thickness((vbX - ) / , (vbY - ) / , (vbX - ) / , (vbY - ) / );
}
else
{
if (reLocation)
{
viewBox.X = svMainPos.X - xoffset - (vbX - / );
viewBox.Y = svMainPos.Y - yoffset - (vbY - / ); CvsGlass.Margin = new Thickness(
CvsGlass.Margin.Left + vbX - glassPoint.X,
CvsGlass.Margin.Top + vbY - glassPoint.Y,
CvsGlass.Margin.Right - vbX + glassPoint.X,
CvsGlass.Margin.Bottom - vbY + glassPoint.Y);
}
}
viewBox.Width = glassWidth;
viewBox.Height = glassHeight;
GlassVB.Viewbox = viewBox;
TxtGlassScale.Hide();
} private void CvsGlass_MouseLeave(object sender, MouseEventArgs e)
{
isGlassDown = false;
} private void CvsGlass_MouseUp(object sender, MouseButtonEventArgs e)
{
isGlassDown = false;
Mouse.Capture(null);
} /// <summary>
/// 重新设置放大镜大小和位置
/// </summary>
public void ReSetGlass()
{
if (BoxList.Count == )
{
return;
} //*2是因为放大镜在vs设计器中显小 放大两倍
BoxList[].SetScaleTrans(CvsGlass, ActualScaleVal * , ActualScaleVal * , false);
if (CvsGlass.Margin.Left >= ActualWidth || CvsGlass.Margin.Top >= ActualHeight)
{
CvsGlass.Margin = new Thickness((ActualWidth - ) / , (ActualHeight - ) / , (ActualWidth - ) / , (ActualHeight - ) / );
}
} #endregion

C#开发PACS医学影像处理系统(十九):Dicom影像放大镜的更多相关文章

  1. C#开发PACS医学影像处理系统(十一):Dicom影像挂片协议

    通俗点说,挂片协议可以看作整个系统的一个相对复杂一点的配置文件,可以用JSON或XML格式来读取与保存, 另外,可以制作一个独立的exe配置程序来管理这些挂片协议. 假设配置了CT的挂片协议的右键菜单 ...

  2. C#开发PACS医学影像处理系统(十二):绘图处理之图形标记

    在医生实际使用过程中,对于有病灶的影像需要一些2D绘图操作,例如对于病灶的标记和测量, 这就牵涉到在WPF中的2D绘图操作技术,一般的思路是监听鼠标的按下和抬起以及运动轨迹,目前整理出的常用绘图和测量 ...

  3. C#开发PACS医学影像处理系统(十五):Dicom影像交叉定位线算法

    1.定位线概念:某个方位的影像在另一个方向的影像上的投影相交线,例如横断面(从头到脚的方向)在矢状面(从左手到右手)上的影像投影面交线. 举个例子:右边的是MR(核磁共振)的某一帧切片,这是从头开始扫 ...

  4. C#开发PACS医学影像处理系统(十六):2D处理之影像平移和缩放

    1.平移,利用WPF中控件边距来控制位移: /// <summary> /// 平移图像 /// </summary> /// <param name="X&q ...

  5. C#开发PACS医学影像处理系统(十四):处理Dicom影像窗宽窗位

    概念解释(网络资料): 窗宽: 窗宽指CT图像所显示的CT 值范围.在此CT值范围内的组织结构按其密度高低从白到黑分为16 个灰阶以供观察对比.例如,窗宽选定为100 Hu ,则人眼可分辨的CT值为1 ...

  6. C#开发PACS医学影像处理系统(十八):Dicom使用LUT色彩增强和反色

    在医生阅片确诊的过程中,当发线疑似病灶时在灰度显示下有时并不清晰,这时候就需要色彩增强效果来使灰度图像变为彩色图像. LUT可以简单的理解为0-255的颜色映射值,例如:彩虹编码,将其打包成LUT格式 ...

  7. C#开发PACS医学影像处理系统(二):界面布局之菜单栏

    在菜单栏布局上,为了使用自定义窗体样式和按钮,我们需要先将窗体设置为无边框,然后添加一个Grid作为菜单栏并置顶,VerticalAlignment="Top" logo图片和标题 ...

  8. C#开发PACS医学影像处理系统(三):界面布局之工具栏

    工具栏布局采用WPF中Grid作为容器,按钮采用自定义样式和图标,并采用Separator分割线: XAML设计器代码: 其中  Style="{StaticResource ButtonS ...

  9. C#开发PACS医学影像处理系统(六):加载Dicom影像

    对于一款软件的扩展性和维护性来说,上层业务逻辑和UI表现一定要自己开发才有控制权,否则项目上线之后容易被掣肘, 而底层图像处理,我们不需要重复造轮子,这里推荐使用fo-dicom,同样基于Dicom3 ...

随机推荐

  1. C++生成元

    生成元对于正整数N,N的数字总和定义为N本身及其数字的总和.当M 是N的数字总和,我们称N为M的生成元. 例如,245的数字总和为256(= 245 + 2 + 4 + 5).因此,245是 256. ...

  2. 团队作业4:第五篇Scrum冲刺博客(歪瑞古德小队)

    目录 一.Daily Scrum Meeting 1.1 会议照片 1.2 项目进展 二.项目燃尽图 三.签入记录 3.1 代码/文档签入记录 3.2 Code Review 记录 3.3 issue ...

  3. Tmux安装和使用

    1.What's tmux tmux 是一个终端复用器: 可以激活多个终端或窗口, 在每个终端都可以单独访问,每一个终端都可以访问,运行和控制各自的程序.tmux类似于screen,可以关闭窗口将程序 ...

  4. linux计算命令

    1.在lammps中通过car文件导出data文件 (进入工作目录xxx cd xxx/ msi2lmp.exe xxx -class I -frc clayff -i -ignore > ou ...

  5. Object中toString方法

    在Java中,所有的对象都是继承自Object,自然继承了toString方法,在当使用System,out.println()里面为一个对象的引用时,自动调用toString方法将对象打印出来.如果 ...

  6. 调试 Ingress Nginx

    由于 Ingress Nginx 是最受欢迎的 Ingress 控制器,因此接下来我们将介绍一些有关调试 ingress-nginx 的技巧. 调试 Ingress Nginx Ingress-ngi ...

  7. 对接接口时,组织参数json出现的问题

    在进行对接第三方接口时,进行参数组装成json的过程中出现参数传递格式错误以及json格式化错误. 在拼接json时,如果json中有对象,则以map的方式组装好所有参数.最后map转成json,不然 ...

  8. Java高级特性——反射机制(第二篇)

    在Java高级特性——反射机制(第一篇)中,写了很多反射的实例,可能对于Class的了解还是有点迷糊,那么我们试着从内存角度去分析一下. Java内存 从上图可以看出,Java将内存分为堆.栈.方法区 ...

  9. 跟我一起学.NetCore之日志作用域及第三方日志框架扩展

    前言 上一节对日志的部分核心类型进行简单的剖析,相信现在再使用日志的时候,应该大概知道怎么一回事了,比如记录器是怎么来的,是如何将日志内容写入到不同目的地的等:当然还有很多细节没深入讲解,抽时间小伙伴 ...

  10. 用java中的Arraylist实现电话本系统管理

    大致思路:创建一个电话本条目的类,在主类中实例化.用实例化的对象调用构造参数接收输入值,然后将此对象存入Arraylist的对象中,实现动态添加电话本条目. 该系统具备添加.删除.修改.查询所有和按姓 ...