简体   繁体   English

FO-DICOM:在C#Windows Forms应用程序中使用呈现的位图调整窗口大小会导致崩溃

[英]FO-DICOM: Resizing a window with a rendered bitmap in a C# Windows Forms application results in crash

I have recently started to evaluate fo-dicom as a possible DICOM library for a future project, so I am quite new with it. 我最近开始将fo-dicom评估为将来项目的可能DICOM库,因此我对此很陌生。

I built a basic C# Windows Forms application that only reads a DICOM file, converts it into a System.Drawing.Bitmap and displays in a PictureBox : 我构建了一个基本的C#Windows Forms应用程序,该应用程序仅读取DICOM文件,将其转换为System.Drawing.Bitmap并显示在PictureBox

public partial class TestFoDicomForm : Form
{
    public TestFoDicomForm()
    {
        InitializeComponent();

        DicomImage di               = new DicomImage("Image_01.dcm");
        Bitmap bmp                  = di.RenderImage().AsBitmap();
        this._pbDicomImage.Image    = bmp;
    }
}

This code functions, but if I start to resize the form, an exception comes more earlier than later telling: 这段代码起作用了,但是如果我开始调整表单的大小 ,则出现异常的时间要比稍后通知的时间更早:

System.ArgumentException: Parameter is not valid. System.ArgumentException:参数无效。

at System.Drawing.Image.get_RawFormat() 在System.Drawing.Image.get_RawFormat()
at System.Drawing.Graphics.DrawImage(Image image, Int32 x, Int32 y, Int32 width, Int32 height) 在System.Drawing.Graphics.DrawImage(图像图像,Int32 x,Int32 y,Int32宽度,Int32高度)
at System.Drawing.Graphics.DrawImage(Image image, Rectangle rect) 在System.Drawing.Graphics.DrawImage(图像图像,矩形rect)
at System.Windows.Forms.PictureBox.OnPaint(PaintEventArgs pe) 在System.Windows.Forms.PictureBox.OnPaint(PaintEventArgs pe)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer) 在System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e,Int16层)
at System.Windows.Forms.Control.WmPaint(Message& m) 在System.Windows.Forms.Control.WmPaint(Message&m)
at System.Windows.Forms.Control.WndProc(Message& m) 在System.Windows.Forms.Control.WndProc(Message&m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 在System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) 在System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 在System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam)

The exception occurs actually in Main() 异常实际上发生在Main()

Application.Run(new TestFoDicomForm());

but I was unable to add a functioning try/catch to investigate what effectively happens. 但是我无法添加正常运行的try/catch来调查有效发生的情况。

I added the reference to fo-dicom 3.0.2 via NuGet (the project's target framework being 4.6.1). 我通过NuGet添加了对fo-dicom 3.0.2的引用(该项目的目标框架为4.6.1)。 Environment: Windows 10 Pro, VS 2017. 环境:Windows 10 Pro,VS 2017。

An interesting thing is that if I produce the bitmap as shown in the code above, then store it, and in the application read it (with no reference to DICOM) and place into the picture box, nothing similar happens. 有趣的是,如果我生成上面代码中所示的位图,然后存储它,然后在应用程序中读取它(不引用DICOM)并放入图片框中,则不会发生类似情况。 This makes me to think that the problem lies in the bitmap itself, but I was unable to discover, what. 这使我认为问题出在位图本身,但我无法发现。

I also have an old test application made with fo-dicom.1.0.37 which does not crash when being resized. 我还有一个使用fo-dicom.1.0.37制作的旧测试应用程序,该应用程序在调整大小时不会崩溃。

I am very curious what the reason may be, how to get rid of this effect or/and what is it I am possibly doing wrong. 我很好奇原因可能是什么,如何摆脱这种影响或/以及我可能做错了什么。

(The test application can be downloaded - I hope - from http://jmp.sh/UGOg8Ai ). (我希望从http://jmp.sh/UGOg8Ai下载测试应用程序)。

This is a known issue in fo-dicom and there is already a fix, that will be included in the next release. 这是fo-dicom中的一个已知问题,已经存在一个修复程序,它将包含在下一版本中。 The explanation is, that the AsBitmap() method returns a Bitmap, whose pixel data points to a memory that is owned by the IImage instance. 解释是,AsBitmap()方法返回一个位图,其像素数据指向IImage实例拥有的内存。 If the IImage instance disposes, then the pointer of the Bitmap is invalid. 如果IImage实例被处置,则位图的指针无效。 This is great for performance reasons and memory consumption because the pixeldata does not have to be duplicated. 由于性能原因和内存消耗,这非常好,因为不必复制像素数据。 Therefore this is not a bug, but as designed. 因此,这不是错误,而是设计错误。

The new release will have two methods: one das behaves like currently to have best performance, and an other that returns a Bitmap with its own pixel data copied. 新版本将提供两种方法:一种das的行为类似于当前具有最佳性能的方法,另一种则返回复制了自​​己的像素数据的Bitmap。

If you have suggenstions or comments, feel free to add them to the issue on github: 如果您有建议或评论,请随时将它们添加到github上的问题中:

https://github.com/fo-dicom/fo-dicom/issues/634 https://github.com/fo-dicom/fo-dicom/issues/634

A colleague of mine knew the answer. 我的一位同事知道答案。 The following code does the thing: 以下代码可以完成此任务:

public partial class TestFoDicomForm : Form
{
    private IImage image;

    public TestFoDicomForm()
    {
        InitializeComponent();

        this.image = new DicomImage("Image_01.dcm").RenderImage();
        Bitmap bmp = image.AsBitmap();
        this.pictureBox1.Image  = bmp;
    }
}

The trick here is that you need to save the instance of your IImage (necessarily in this form, as IImage , due to the return type of RenderImage() ). 这里的技巧是,您需要保存IImage的实例(由于RenderImage()的返回类型,因此必须以IImage形式保存)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM