WPF读取dicom序列:实现上一帧、下一帧、自动播放、暂停

一、整体设计概况

  1. 创建WPF程序使用.Net Framework4.8
  2. 定义Image控件展示图像
  3. 增加标签展示dcm文件信息
  4. 规划按钮触发对应的事件:上一帧、下一帧、自动播放、暂停、缩放、播放速率

二、页面展示

 三、代码逻辑分析

  1. Windows窗体加载Loaded事件:生成初始图像信息
  2. Windows窗体加载MouseWheel事件:用于图片缩放
  3. 定义Grid的行数
  4. 配置Image、Label、TextBox、Button
  5. 组装各个逻辑

四、后端代码展示

    /// <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

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

双叶红于二月花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值