FO-DICOM: изменение размера окна с отображенным растровым изображением в приложении C# Windows Forms приводит к сбою
Недавно я начал оценивать 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: параметр недействителен.
в System.Drawing.Image.get_RawFormat()
в System.Drawing.Graphics.DrawImage(изображение изображения, Int32 x, Int32 y, Int32 ширина, Int32 высота)
в System.Drawing.Graphics.DrawImage(изображение, прямоугольник)
в System.Windows.Forms.PictureBox.OnPaint(PaintEventArgs pe)
в System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, слой Int16)
в System.Windows.Forms.Control.WmPaint (Сообщение & m)
в System.Windows.Forms.Control.WndProc (сообщение & m)
в System.Windows.Forms.Control.ControlNativeWindow.OnMessage (Message& m)
в System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
в System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
Исключение происходит на самом деле в Main()
Application.Run(new TestFoDicomForm());
но я не смог добавить функционирование try/catch
исследовать, что эффективно происходит.
Я добавил ссылку на fo-dicom 3.0.2 через NuGet (целевой структурой проекта является 4.6.1). Среда: Windows 10 Pro, VS 2017.
Интересно, что если я создаю растровое изображение, как показано в приведенном выше коде, сохраняю его, а в приложении считываю его (без ссылки на DICOM) и помещаю в графическое окно, ничего подобного не происходит. Это заставляет меня думать, что проблема заключается в самом растровом изображении, но я не смог обнаружить, что.
У меня также есть старое тестовое приложение, созданное с помощью fo-dicom.1.0.37, которое не вылетает при изменении размера.
Мне очень любопытно, в чем может быть причина, как избавиться от этого эффекта и / или что я, возможно, делаю неправильно.
(Тестовое приложение можно загрузить - я надеюсь - с http://jmp.sh/UGOg8Ai).
2 ответа
Мой коллега знал ответ. Следующий код делает это:
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
(обязательно в таком виде, как IImage
, из-за типа возврата RenderImage()
).
Это известная проблема в fo-dicom, и уже есть исправление, которое будет включено в следующий выпуск. Объяснение заключается в том, что метод AsBitmap() возвращает растровое изображение, данные пикселей которого указывают на память, которая принадлежит экземпляру IImage. Если экземпляр IImage удаляется, то указатель битовой карты недействителен. Это очень удобно с точки зрения производительности и потребления памяти, поскольку пиксельные данные не должны дублироваться. Поэтому это не ошибка, а как задумано.
В новом выпуске будет два метода: один das ведет себя так, как в настоящее время, чтобы иметь лучшую производительность, а другой - возвращает битовую карту со скопированными собственными пиксельными данными.
Если у вас есть предложения или комментарии, не стесняйтесь добавлять их к проблеме на github: