C#开发PACS医学影像处理系统(十九):Dicom影像放大镜
在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影像放大镜的更多相关文章
- C#开发PACS医学影像处理系统(十一):Dicom影像挂片协议
通俗点说,挂片协议可以看作整个系统的一个相对复杂一点的配置文件,可以用JSON或XML格式来读取与保存, 另外,可以制作一个独立的exe配置程序来管理这些挂片协议. 假设配置了CT的挂片协议的右键菜单 ...
- C#开发PACS医学影像处理系统(十二):绘图处理之图形标记
在医生实际使用过程中,对于有病灶的影像需要一些2D绘图操作,例如对于病灶的标记和测量, 这就牵涉到在WPF中的2D绘图操作技术,一般的思路是监听鼠标的按下和抬起以及运动轨迹,目前整理出的常用绘图和测量 ...
- C#开发PACS医学影像处理系统(十五):Dicom影像交叉定位线算法
1.定位线概念:某个方位的影像在另一个方向的影像上的投影相交线,例如横断面(从头到脚的方向)在矢状面(从左手到右手)上的影像投影面交线. 举个例子:右边的是MR(核磁共振)的某一帧切片,这是从头开始扫 ...
- C#开发PACS医学影像处理系统(十六):2D处理之影像平移和缩放
1.平移,利用WPF中控件边距来控制位移: /// <summary> /// 平移图像 /// </summary> /// <param name="X&q ...
- C#开发PACS医学影像处理系统(十四):处理Dicom影像窗宽窗位
概念解释(网络资料): 窗宽: 窗宽指CT图像所显示的CT 值范围.在此CT值范围内的组织结构按其密度高低从白到黑分为16 个灰阶以供观察对比.例如,窗宽选定为100 Hu ,则人眼可分辨的CT值为1 ...
- C#开发PACS医学影像处理系统(十八):Dicom使用LUT色彩增强和反色
在医生阅片确诊的过程中,当发线疑似病灶时在灰度显示下有时并不清晰,这时候就需要色彩增强效果来使灰度图像变为彩色图像. LUT可以简单的理解为0-255的颜色映射值,例如:彩虹编码,将其打包成LUT格式 ...
- C#开发PACS医学影像处理系统(二):界面布局之菜单栏
在菜单栏布局上,为了使用自定义窗体样式和按钮,我们需要先将窗体设置为无边框,然后添加一个Grid作为菜单栏并置顶,VerticalAlignment="Top" logo图片和标题 ...
- C#开发PACS医学影像处理系统(三):界面布局之工具栏
工具栏布局采用WPF中Grid作为容器,按钮采用自定义样式和图标,并采用Separator分割线: XAML设计器代码: 其中 Style="{StaticResource ButtonS ...
- C#开发PACS医学影像处理系统(六):加载Dicom影像
对于一款软件的扩展性和维护性来说,上层业务逻辑和UI表现一定要自己开发才有控制权,否则项目上线之后容易被掣肘, 而底层图像处理,我们不需要重复造轮子,这里推荐使用fo-dicom,同样基于Dicom3 ...
随机推荐
- AS报错:gradle project sync failed
情形一: Android studio下突然报错: gradle project sync failed.Basic functionality(e.g.editing,debugging) will ...
- 【Flutter 实战】一文学会20多个动画组件
老孟导读:此篇文章是 Flutter 动画系列文章第三篇,后续还有动画序列.过度动画.转场动画.自定义动画等. Flutter 系统提供了20多个动画组件,只要你把前面[动画核心](文末有链接)的文章 ...
- Unix I/O
Unix I/O 打开文件 一个应用程序通过要求内核打开相应的文件,来宣告它想要访问一个I/O设备.内核返回一个小的非负整数,叫做描述符,它在后续对此文件的所有操作中标识这个文件.内核记录有关这个打开 ...
- python 03 常用操作符
1. e记法,科学计数法. AeB A,B为整数,A*10的B次方. 2. 逻辑运算,真为1,假为0,最好不使用这个计算 true(1) false(0) true+true=2 3.类型转 ...
- Mybatis_day2
二 mybatis配置详解 MyBatis最关键的组成部分是SqlSessionFactory,我们可以从中获取SqlSession, 并执行映射的SQL语句.SqlSessionFactory对象可 ...
- 使用client-go自定义开发Kubernetes
参考链接:使用client-go自定义开发Kubernetes 1.本地运行 apiserver demo [root@wangjq demo]# apiserver-boot run local / ...
- dcoker 小应用(一)
docker 创建Ubuntu系统 1.创建Dockerfile #ubuntu:14.04 image FROM ubuntu:14.04 MAINTAINER XXX, xxx@xxx.com R ...
- IE浏览器连接WebSocket报错:java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
在项目开发中整合了WebSocket,本来没什么问题了,但是偶尔发现用IE浏览器打开web端不能推送消息,因为PC端与服务器建立连接失败了.网上查了很多资料, 又看了看源码,都不对症:又怀疑是Spri ...
- 基于 abp vNext 微服务开发的敏捷应用构建平台 - 设计构想
许多中小企业的管理模式都是在自身的发展过程中不断摸索,逐步建立起来的,每一家都有其独有的管理模式,而且随着企业的不断发展,管理模式也在不断变化中.企业在发展壮大的过程中离不开信息化系统的支撑,企业在构 ...
- Docker-Docker容器跨主机通信
Docker默认的网络环境下,单台主机上的Docker容器可以通过docker0网桥直接通信,而不同主机上的Docker容器之间只能通过在主机上做端口映射进行通信.这种端口映射方式对很多集群应用来说极 ...