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:

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

Другие вопросы по тегам