一、整体设计概况
- 创建WPF程序使用.Net Framework4.8
- 定义Image控件展示图像
- 增加标签展示dcm文件信息
- 规划按钮触发对应的事件:上一帧、下一帧、自动播放、暂停、缩放、播放速率
二、页面展示
三、代码逻辑分析
- Windows窗体加载Loaded事件:生成初始图像信息
- Windows窗体加载MouseWheel事件:用于图片缩放
- 定义Grid的行数
- 配置Image、Label、TextBox、Button
- 组装各个逻辑
四、后端代码展示
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
/// <summary>
/// 当前文件
/// </summary>
private FileInfo _currentFileInfo = null;
private LinkedList<FileInfo> _linkedList = new LinkedList<FileInfo>();
private bool isSuspend = false;
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
imgVTK.Source = GetImage(GetFiles().First(), out string parentId, out string description);
lblParentIdValue.Content = parentId;
lblDescriptionValue.Content = description;
}
private async void btnAutoPlay_Click(object sender, RoutedEventArgs e)
{
int millisecondsDelay = 333;
if (!string.IsNullOrEmpty(txtRate.Text))
{
if (int.TryParse(txtRate.Text, out int milliseconds))
{
milliseconds = milliseconds * 1000;
millisecondsDelay = milliseconds / 3;
}
}
isSuspend = false;
foreach (var item in GetFiles())
{
imgVTK.Source = GetImage(item, out string parentId, out string description);
lblParentIdValue.Content = parentId;
lblDescriptionValue.Content = description;
if (isSuspend == true)
{
break;
}
await Task.Delay(millisecondsDelay);
}
}
private void btnUp_Click(object sender, RoutedEventArgs e)
{
var node = GetFiles().Find(_currentFileInfo);
FileInfo fileInfo;
if (node.Previous?.Value == null)
fileInfo = GetFiles().Last();
else
fileInfo = node.Previous.Value;
imgVTK.Source = GetImage(fileInfo, out string parentId, out string description);
lblParentIdValue.Content = parentId;
lblDescriptionValue.Content = description;
}
private void btnDown_Click(object sender, RoutedEventArgs e)
{
var node = GetFiles().Find(_currentFileInfo);
FileInfo fileInfo;
if (node.Next?.Value == null)
fileInfo = GetFiles().First();
else
fileInfo = node.Next.Value;
imgVTK.Source = GetImage(fileInfo, out string parentId, out string description);
lblParentIdValue.Content = parentId;
lblDescriptionValue.Content = description;
}
private void btnSuspend_Click(object sender, RoutedEventArgs e)
{
isSuspend = true;
}
private void Window_MouseWheel(object sender, MouseWheelEventArgs e)
{
Point p = e.MouseDevice.GetPosition(imgVTK);
Matrix m = imgVTK.RenderTransform.Value;
if (e.Delta > 0)
m.ScaleAtPrepend(1.1, 1.1, p.X, p.Y);
else
m.ScaleAtPrepend(1 / 1.1, 1 / 1.1, p.X, p.Y);
imgVTK.RenderTransform = new MatrixTransform(m);
}
#region 私有方法
/// <summary>
/// 获取文件源
/// </summary>
/// <returns></returns>
private LinkedList<FileInfo> GetFiles()
{
if (_linkedList.Count > 0)
{
return _linkedList;
}
var baseDirectionary = string.Concat(AppDomain.CurrentDomain.BaseDirectory, "\\", "digest_article");
DirectoryInfo directoryInfo = new DirectoryInfo(baseDirectionary);
var files = directoryInfo.GetFiles();
_linkedList = new LinkedList<FileInfo>(files);
return _linkedList;
}
/// <summary>
/// 获取图片源
/// </summary>
/// <param name="fileInfo"></param>
/// <param name="parentId"></param>
/// <param name="description"></param>
/// <returns></returns>
private ImageSource GetImage(FileInfo fileInfo, out string parentId, out string description)
{
parentId = null;
description = null;
Dicom.Imaging.ImageManager.SetImplementation(WPFImageManager.Instance);
var dcmFile = DicomFile.Open(fileInfo.FullName);
var dcmDataSet = dcmFile.Dataset;
foreach (DicomElement item in dcmDataSet)
{
var key = item.Tag.DictionaryEntry.Name.Replace(" ", "").ToLower();
if (key == "seriesdescription")
{
description = Encoding.UTF8.GetString(item.Buffer.Data);
}
if (key == "patientid")
{
parentId = Encoding.UTF8.GetString(item.Buffer.Data);
}
}
DicomImage dcmImage = new DicomImage(dcmDataSet);
var iImage = dcmImage.RenderImage();
ImageSource imageSource = iImage.AsWriteableBitmap();
// 设定起始文件源
_currentFileInfo = fileInfo;
return imageSource;
}
#endregion
}
五、结果展示
六、源码地址
链接:https://pan.baidu.com/s/1hH9xbUL3T6oxcxx0oG9-9Q
提取码:clo0