在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. Jmeter系列(50)- 详解 If 控制器

    如果你想从头学习Jmeter,可以看看这个系列的文章哦 https://www.cnblogs.com/poloyy/category/1746599.html 简单介绍 可以通过条件来控制是否运行其 ...

  2. 编译u-boot时候,make distclean 出现rm:无法删除,****是一个目录

    今天在编译u-boot的时候,make distclean,出现了rm:无法删除 "include/asm-arm/arch": 是一个目录.经过查看网友的解决办法,已经解决了. ...

  3. IDEA报错:Class JavaLaunchHelper is implemented in both

    在IDEA运行一个程序时报错: Class JavaLaunchHelper is implemented in both 这个错误是Mac下Java 的一个bug,意思是这个JavaLaunchHe ...

  4. Android低功耗蓝牙总结

    这里只列出重点原理内容,更加细节的内容请阅读前面文章 首先要搞清楚一点,我们在 Android 中通过 SDK 获得的蓝牙广播包是经过底层的 SDK 给我们处理过的,是一个长度为 62 的字节数组.这 ...

  5. Hello-Annie

    Annie theme Annie是一个简单的Hexo博客主题,如果你喜欢散文.诗歌.小说......那么它可能合你心意! ☞预览-1,☞预览-2 Features 文艺.优雅.简洁的博客主题 页头随 ...

  6. CSS 段落/换行/缩进

    CSS 段落/换行/缩进 1.盒模型 box-sizing: content-box|border-box|inherit; content-box(默认) : 实际宽度/高度 = width/hei ...

  7. hyperledger-fabric环境快速搭建踩坑集锦(实用)

    安装docker 及 docker-compose 安装docker没什么好说的,一部分教程都给出了指令,在这里就不谈了. docker-compose不同的教程给出了不同的方法,在这里介绍一种极为快 ...

  8. Java面试题(Redis篇)

    Redis 179.redis 是什么?都有哪些使用场景? Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. ...

  9. HttpWatch汉化版带详细的使用教程下载

    http://www.wocaoseo.com/thread-303-1-1.html HttpWatch是强大的网页数据分析工具.集成在Internet Explorer工具栏.包括网页摘要.Coo ...

  10. Python数据清洗:提取爬虫文本中的电话号码

    步骤索引 效果展示 注意事项 代码 很多人学习python,不知道从何学起.很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手.很多已经做案例的人,却不知道如何去学习更加高深的知识. ...