在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. 《Java从入门到失业》第一章:计算机基础知识(一):二进制和十六进制

    0 前言 最近7年来的高强度工作和不规律的饮食作息,压得我有些喘不过气,身体也陆续报警.2018年下半年的一场病,让我意识到了这个问题的严重性,于是开始强制自己有规律饮食和作息,并辅以健身锻炼,不到2 ...

  2. failed to find romfile "efi-virtio.rom"

    问题:failed to find romfile "efi-virtio.rom" 解决:apt-get install ipxe-qemu

  3. 查询Linux CPU架构

    一.背景 Ubuntu上需要安装测试个软件wkhtmltopdf,但是下载时,需要知道系统架构,故做记录 二.查看linux架构 dpkg 命令 dpkg 的命令可用于查看 Debian/ Ubunt ...

  4. 设计模式 | Spring中用到的设计模式,你知道几个?

    设计模式无处不在,因为它就来自于我们的日常生活,提炼于生活经验. 正握在你手中的手机,不能用220V的电压直接充电,需要一个专门的电源适配器(充电器)才行.摆在你桌上的电脑也是一样的,都需要" ...

  5. Vue基础(三)---- 组件化开发

    基本结构: ◆1.组件化开发思想 ◆2.组件注册 ◆3.Vue调试工具用法 ◆4.组件间数据交互 ◆5.组件插槽 ◆6.基于组件的案例   ◆1.组件化开发思想 优点: 提高开发效率 方便重复使用 简 ...

  6. 微信小程序如何快速开通流量主

    1.先开发小程序,小程序需要有亮点,毕竟新颖(这样别人才更好去点击查看) 2.条件是独立访客(UV)不低于1000,1000人说多不多,说少也不少,因为小程序是没有链接的,是不可以进行一个流量刷取的, ...

  7. miniapp基础

    文件目录 component 公共组件 img 图片 libs 插件,外部引入 pages 页面 utils 封装公共方法 wxParse html转wxml-->插件 app.js 公共逻辑方 ...

  8. Database4.exe用来导入excel

    从ACCESS数据库导出的EXCEL表格,可以通过database4.exe来连接,并导出sql脚本,再用database4.exe来连接ACCESS并先创建于脚本结构一致的表,然后复制脚本,从新生成 ...

  9. 使用代码给Unity中的动画片段绑定回调函数

    在制作动作游戏的时候,需要播放许多动画,同时还有个需求,那就是动画播放到一定时间时,给一个回调函数,好做对应的状态变更, 我查了一下,发现如果使用的是unity自带的动画系统,要做到这样的话,需要这样 ...

  10. GLSL 着色器程序

    除了使用Cg/HSL 着色器程序以外, OpenGL 着色器语言(GLSL)着色器可以直接书写shader. 然而,使用原生的GLSL只推荐作为测试使用,或者你清晰的知道你的目标平台是 Mac OS ...