FO-DICOM:在 C# Windows Forms 应用程序中使用呈现的位图调整 window 的大小会导致崩溃
FO-DICOM: Resizing a window with a rendered bitmap in a C# Windows Forms application results in crash
我最近开始评估 fo-dicom 作为未来项目的可能 DICOM 库,所以我对它很陌生。
我构建了一个基本的 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;
}
}
这段代码起作用了,但是如果我开始调整表单的大小,一个异常来得比后来告诉的更早:
System.ArgumentException: Parameter is not valid.
at System.Drawing.Image.get_RawFormat()
at System.Drawing.Graphics.DrawImage(Image image, Int32 x, Int32 y, Int32 width, Int32 height)
at System.Drawing.Graphics.DrawImage(Image image, Rectangle rect)
at System.Windows.Forms.PictureBox.OnPaint(PaintEventArgs pe)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
异常实际发生在Main()
Application.Run(new TestFoDicomForm());
但我无法添加功能 try/catch
来调查实际发生的情况。
我通过 NuGet 添加了对 fo-dicom 3.0.2 的引用(该项目的目标框架是 4.6.1)。环境:Windows 10 Pro,VS 2017。
有趣的是,如果我按照上面的代码生成位图,然后存储它,然后在应用程序中读取它(不引用 DICOM)并将其放入图片框中,则不会发生类似情况。这让我认为问题出在位图本身,但我无法发现,什么。
我还有一个用 fo-dicom.1.0.37 制作的旧测试应用程序,它在调整大小时不会崩溃。
我很好奇可能是什么原因,如何摆脱这种影响or/and我可能做错了什么。
(可以下载测试应用程序 - 我希望 - 来自 http://jmp.sh/UGOg8Ai)。
我的一位同事知道答案。以下代码执行此操作:
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;
}
}
这里的技巧是您需要保存 IImage
的实例(由于 [=13= 的 return 类型,因此必须以这种形式保存为 IImage
]).
这是 fo-dicom 中的一个已知问题,并且已经有一个修复程序,将包含在下一个版本中。
解释是,AsBitmap() 方法 returns 一个位图,其像素数据指向 IImage 实例拥有的内存。如果 IImage 实例处置,则 Bitmap 的指针无效。
出于性能原因和内存消耗,这非常有用,因为不必复制像素数据。因此这不是错误,而是设计的。
新版本将有两种方法:一种是 das 表现得像当前一样具有最佳性能,另一种是 returns 复制了自己的像素数据的位图。
如果您有任何建议或意见,请随时将其添加到 github 上的问题:
我最近开始评估 fo-dicom 作为未来项目的可能 DICOM 库,所以我对它很陌生。
我构建了一个基本的 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;
}
}
这段代码起作用了,但是如果我开始调整表单的大小,一个异常来得比后来告诉的更早:
System.ArgumentException: Parameter is not valid.
at System.Drawing.Image.get_RawFormat()
at System.Drawing.Graphics.DrawImage(Image image, Int32 x, Int32 y, Int32 width, Int32 height)
at System.Drawing.Graphics.DrawImage(Image image, Rectangle rect)
at System.Windows.Forms.PictureBox.OnPaint(PaintEventArgs pe)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
异常实际发生在Main()
Application.Run(new TestFoDicomForm());
但我无法添加功能 try/catch
来调查实际发生的情况。
我通过 NuGet 添加了对 fo-dicom 3.0.2 的引用(该项目的目标框架是 4.6.1)。环境:Windows 10 Pro,VS 2017。
有趣的是,如果我按照上面的代码生成位图,然后存储它,然后在应用程序中读取它(不引用 DICOM)并将其放入图片框中,则不会发生类似情况。这让我认为问题出在位图本身,但我无法发现,什么。
我还有一个用 fo-dicom.1.0.37 制作的旧测试应用程序,它在调整大小时不会崩溃。
我很好奇可能是什么原因,如何摆脱这种影响or/and我可能做错了什么。
(可以下载测试应用程序 - 我希望 - 来自 http://jmp.sh/UGOg8Ai)。
我的一位同事知道答案。以下代码执行此操作:
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;
}
}
这里的技巧是您需要保存 IImage
的实例(由于 [=13= 的 return 类型,因此必须以这种形式保存为 IImage
]).
这是 fo-dicom 中的一个已知问题,并且已经有一个修复程序,将包含在下一个版本中。 解释是,AsBitmap() 方法 returns 一个位图,其像素数据指向 IImage 实例拥有的内存。如果 IImage 实例处置,则 Bitmap 的指针无效。 出于性能原因和内存消耗,这非常有用,因为不必复制像素数据。因此这不是错误,而是设计的。
新版本将有两种方法:一种是 das 表现得像当前一样具有最佳性能,另一种是 returns 复制了自己的像素数据的位图。
如果您有任何建议或意见,请随时将其添加到 github 上的问题: