zoukankan      html  css  js  c++  java
  • 实现一个DICOM浏览工具 ——显示图像

    实现一个DICOM浏览工具——显示图像

    在通过fo-dicom解析图像后,需要把图像显示到窗体中,在xaml中添加Image控件,命名为 DcmImage。

      public async Task OpenAsync(string filename)
          {
              var file = await DicomFile.OpenAsync(filename);
              if (file.Dataset.Contains(DicomTag.PixelData))
              {
                  var dicomImage = new DicomImage(file.Dataset);
                  // fo-dicom中默认是用WinFormImageManager进行图像管理的,如果想在wpf中使用,需要指定为WpfImageManager类
                  // 之所以要在这里指定ImageMnager,是因为在DicomImage的RenderImage方法中会调用ImageManager实现类的CreateImageImpl方法获取相对应的图像数据
                  ImageManager.SetImplementation(ViewerImageManager.Instance); 
                  var frames = Enumerable.Range(0, dicomImage.NumberOfFrames)
                      .Select(frame => dicomImage.RenderImage(frame).As<ImageSource>())
                      .ToList();
                  if (frames.Count > 0)
                  {
                      DcmImage.Source = frames[0];
                  }
              }
          }
    

    在fo-dicom源码中包含了WPFImageManager,但是我通过nuget安装后的找不到这个类,不知道为什么,后边没办法,只能参考github上边的自己写了一个ImageManager类,用来做图像处理的管理工具,具体代码如下:

    namespace DcmViewer
        {
        using Dicom.Imaging;
        public sealed class ViewerImageManager : ImageManager
        {
            #region FIELDS
            public static readonly ImageManager Instance;
            #endregion
    
            #region CONSTRUCTORS
            
            static ViewerImageManager()
            {
                Instance = new ViewerImageManager();
            }
    
            #endregion
    
            #region PROPERTIES 
            public override bool IsDefault { 
                get
                {
                    return false;
                }
            }
            #endregion
    
    
            #region METHODS
    
            protected override IImage CreateImageImpl(int width, int height)
            {
                return new ViewerImage(width, height);
            }
    
            #endregion
    
        }
      }
    

    上边的ViewerImageManager还缺少一个对应的ViewerImage类,代码如下:

    namespace DcmViewer
    {
        public sealed class ViewerImage : ImageBase<WriteableBitmap>
        {
            #region FIELDS
            private const double DPI = 96;
            #endregion
    
            #region CONSTRUCTORS
    
            public ViewerImage(int width, int height): base(width, height, new Dicom.IO.PinnedIntArray(width * height), null)
            {            
            }
    
            private ViewerImage(int widht, int height, PinnedIntArray pixels, WriteableBitmap image) : base(widht, height, pixels, image)
            {
            }
            #endregion
    
            #region METHODS
            
            public override void Render(int components, bool flipX, bool flipY, int rotation)
            {
                var bitmap = CreateBitMap(width, height, components, pixels.Data);
                image = ApplyFlipRotate(bitmap, flipX, flipY, rotation);
            }
    
            public override void DrawGraphics(IEnumerable<IGraphic> graphics)
            {
                foreach (var graphic in graphics)
                {
                    var layer = graphic.RenderImage(null).As<WriteableBitmap>();
    
                    var overlay = new int[graphic.ScaledWidth * graphic.ScaledHeight];
                    var stride = 4 * graphic.ScaledWidth;
                    layer.CopyPixels(overlay, stride, 0);
    
                    image.WritePixels(
                        new Int32Rect(
                            graphic.ScaledOffsetX,
                            graphic.ScaledOffsetY,
                            graphic.ScaledWidth,
                            graphic.ScaledHeight),
                        overlay,
                        stride,
                        0);
                }
            }
    
            public override IImage Clone()
            {
                return new ViewerImage(
                    width,
                    height,
                    new PinnedIntArray(pixels.Data),
                    image == null ? null : new WriteableBitmap(image));
            }
    
            private static WriteableBitmap CreateBitMap(int width, int height, int components, int[] pixelData)
            {
                var format = components == 4 ? PixelFormats.Bgra32 : PixelFormats.Bgr32;
                var bitmap = new WriteableBitmap(width, height, DPI, DPI, format, null);
                bitmap.Lock();
                Marshal.Copy(pixelData, 0, bitmap.BackBuffer, pixelData.Length);
                bitmap.AddDirtyRect(new Int32Rect(0, 0, width, height));
                bitmap.Unlock();
                return bitmap;
            }
    
            private static WriteableBitmap ApplyFlipRotate(WriteableBitmap bitmap, bool flipX, bool flipY, int rotation)
            {
                if (rotation == 0 && !flipX && !flipY)
                {
                    return bitmap;
                }
    
                var rotFlipTransform = new TransformGroup();
                rotFlipTransform.Children.Add(new RotateTransform(rotation));
                rotFlipTransform.Children.Add(new ScaleTransform(flipX ? -1 : 1, flipY ? -1 : 1));
    
                return new WriteableBitmap(new TransformedBitmap(bitmap, rotFlipTransform));
            }
            #endregion
        }
    }
    
    

    在实现类OpenButton的响应函数后,实现初步的简单显示效果如下:

  • 相关阅读:
    两个简单的画验证码图形程序
    Cisco路由技术基础知识详解
    网络管理中的常用命令
    网络管理中的常用命令
    基于SNMP的MIB库访问实现
    SNMP编程基础
    SNMP编程基础
    Cisco路由技术基础知识详解
    两个简单的画验证码图形程序
    模版方法
  • 原文地址:https://www.cnblogs.com/NoPolar/p/14416283.html
Copyright © 2011-2022 走看看