医学dicom游览器C#源码
using Dicom;using Dicom.Imaging;using Dicom.Imaging.Codec;using DICOMBrower.Command;using DICOMBrower.Utils;using System;using System.Collections.Generic;using System.Drawing;using System.Reflection;using System.Windows.Input;using System.Windows.Media.Imaging;namespace DICOMBrower.ViewModel{ class DICOMViewModel : NotifyPropertyObject { #region 属性 /// <summary> /// DICOM文件 /// </summary> DicomFile _dicomFile; DicomImage _dicomImage; BitmapImage _image; double _defaultWidth; double _defaultHeight; double _pointX; double _pointY; Cursor _cur; List<Model.Dicom> _dicomElements = new List<Model.Dicom>(); #endregion #region 字段 public DicomFile DcmFile { get => _dicomFile; set { _dicomFile = value; RasiePropertyChanged("DcmFile"); } } public DicomImage DcmImage { get => _dicomImage; set { _dicomImage = value; RasiePropertyChanged("DcmImage"); } } public BitmapImage Image { get => _image; set { _image = value; RasiePropertyChanged("Image"); } } public Cursor Cur { get => _cur; set { _cur = value; RasiePropertyChanged("Cur"); } } public List<Model.Dicom> DicomElements { get => _dicomElements; set { _dicomElements = value; RasiePropertyChanged("DicomElements"); } } #endregion #region 方法 private void SetDicomWinWidthWinCenter() { } #endregion public DelegateCommand OpenFile { get { return new DelegateCommand((obj) => { // 在WPF中, OpenFileDialog位于Microsoft.Win32名称空间 Microsoft.Win32.OpenFileDialog dialog = new Microsoft.Win32.OpenFileDialog { Filter = "dicom影像|*.dcm" }; if (dialog.ShowDialog() == false) { return; //lblFileName.Content = dialog.FileName; } _dicomFile = DicomFile.Open(dialog.FileName); DicomFile newDcmFile = null; // 如果Dicom图像是压缩过的 可能有问题 if (_dicomFile.FileMetaInfo.TransferSyntax.IsEncapsulated) { // 转换DICOM传输语法 DicomTranscoder dicomTranscoder = new DicomTranscoder(_dicomFile.FileMetaInfo.TransferSyntax, DicomTransferSyntax.ExplicitVRLittleEndian); newDcmFile = dicomTranscoder.Transcode(_dicomFile); } DicomDataset dicomDataset = newDcmFile == null ? _dicomFile.Dataset : newDcmFile.Dataset; //// 注意点:获取的像素值需要进行转化 实际像素值 = RescaleSlope * 获取像素值 RescaleIntercept,若BitsAllocated超过8会超出颜色值的表示范围0~255需要对其进行转化. ////读取dcm格式文件里相关元素值 //var strInstanceNumber = dicomDataset.GetString(DicomTag.InstanceNumber); //var nWidth = dicomDataset.GetSingleValue<int>(DicomTag.Columns); //var nHeight = dicomDataset.GetSingleValue<int>(DicomTag.Rows); //// 窗宽 //var dWindowWidth = dicomDataset.GetSingleValue<double>(DicomTag.WindowWidth); //// 窗位 //var dWindowCenter = dicomDataset.GetSingleValue<double>(DicomTag.WindowCenter); //// 1表示灰度图像3表示彩色图像 //var nSamplesPerPixel = dicomDataset.GetSingleValueOrDefault<int>(DicomTag.SamplesPerPixel, 1); //// 像素值的比例系数 //var dRescaleSlope = dicomDataset.GetSingleValueOrDefault<double>(DicomTag.RescaleSlope, 1); //// 像素值的比例参数 //var dRescaleIntercept = dicomDataset.GetSingleValueOrDefault<double>(DicomTag.RescaleIntercept, 0); //// 每一种颜色值所分配的存储位数 //var nBitsAllocated = dicomDataset.GetSingleValue<int>(DicomTag.BitsAllocated); //// 像素值存储的最高位 //var nHighBit = dicomDataset.GetSingleValue<int>(DicomTag.HighBit); //var strNumberOfFrames = String.Empty; //dicomDataset.TryGetString(DicomTag.NumberOfFrames, out strNumberOfFrames); //// 像素 //DicomElement dicomElement = dicomDataset.GetDicomItem<DicomElement>(DicomTag.PixelData); //byte[] pixData = dicomElement.Buffer.Data; // 解析DICOM数据 List<Model.Dicom> dicomElements = new List<Model.Dicom>(); //_dicomElements.Clear(); Type type = typeof(DicomTag); FieldInfo[] fieldInfos = type.GetFields(BindingFlags.Public | BindingFlags.Static); DicomElement dicomElement; foreach (var field in fieldInfos) { dicomElement = dicomDataset.GetDicomItem<DicomElement>((DicomTag)field.GetValue(null)); if (dicomElement != null) { Model.Dicom dicom = new Model.Dicom { Tag = dicomElement.Tag.ToString(), Vr = dicomElement.ValueRepresentation.ToString(), Vm = dicomElement.Count, Vl = (int)dicomElement.Length, Value = dicomElement.Get<string>(), Name = dicomElement.Tag.DictionaryEntry.Name }; dicomElements.Add(dicom); } dicomElement = _dicomFile.FileMetaInfo.GetDicomItem<DicomElement>((DicomTag)field.GetValue(null)); if (dicomElement != null) { Model.Dicom dicom = new Model.Dicom { Tag = dicomElement.Tag.ToString(), Vr = dicomElement.ValueRepresentation.ToString(), Vm = dicomElement.Count, Vl = (int)dicomElement.Length, Value = dicomElement.Get<string>(), Name = dicomElement.Tag.DictionaryEntry.Name }; dicomElements.Add(dicom); } } DicomElements = dicomElements; _dicomImage = new DicomImage(dicomDataset); // 设置默认DICOM影像窗宽窗位 _defaultWidth = _dicomImage.WindowWidth; _defaultHeight = _dicomImage.WindowCenter; // 将DICOM影像装换为bitmap Bitmap bitmap = _dicomImage.RenderImage().Clone().As<Bitmap>(); // 转化为BitmapImage Image = BitmapUtil.BitmapToBitmapImage(bitmap); bitmap.Dispose(); }); } } public DelegateCommand<MouseEventArgs> LeftPressedAndMouseMove { get { return new DelegateCommand<MouseEventArgs>(new Action<MouseEventArgs>((e) => { var point = e.GetPosition(e.Device.Target); var min = (2 * _dicomImage.WindowCenter - _dicomImage.WindowWidth) / 2.0 0.5; var max = (2 * _dicomImage.WindowCenter _dicomImage.WindowWidth) / 2.0 0.5; _dicomImage.WindowWidth = point.X / _pointX * _defaultWidth; if (_dicomImage.WindowWidth < min) { _dicomImage.WindowWidth = min; } if (_dicomImage.WindowWidth > max) { _dicomImage.WindowWidth = max; } _dicomImage.WindowCenter = point.Y / _pointY * _defaultHeight; if (_dicomImage.WindowCenter < min) { _dicomImage.WindowCenter = min; } if (_dicomImage.WindowCenter > max) { _dicomImage.WindowCenter = max; } // 将DICOM影像装换为bitmap Bitmap bitmap = _dicomImage.RenderImage().As<Bitmap>(); // 转化为BitmapImage Image = BitmapUtil.BitmapToBitmapImage(bitmap); bitmap.Dispose(); }), new Func<MouseEventArgs, bool>((e) => { if (e.LeftButton == MouseButtonState.Pressed) { Cur = Cursors.SizeWE; if (_pointX == 0 && _pointY == 0) { var point = e.GetPosition(e.Device.Target); _pointX = point.X; _pointY = point.Y; } return true; } return false; })); } } public DelegateCommand<MouseEventArgs> MouseLeftButtonUp { get { return new DelegateCommand<MouseEventArgs>((e) => { // 设置默认DICOM影像窗宽窗位 _defaultWidth = _dicomImage.WindowWidth; _defaultHeight = _dicomImage.WindowCenter; _pointX = 0; _pointY = 0; Cur = Cursors.Arrow; }); } } }}
评论