Исключение нарушения доступа к растровому изображению с изображением камеры

#c# #wpf #bitmap #camera #eventargs

Вопрос:

В моем приложении WPF изображения делаются с помощью камеры, использующей вид, а затем передаются в виде растровых изображений другому, когда он закрыт с помощью параметров событий. Однако, когда я затем пытаюсь обработать изображения, я получаю исключение AccessViolationException. Этого не происходит, когда я обрабатываю изображения до их передачи или когда я использую изображения, загруженные из файла.

Получение изображения с камеры ( PtCamera класс-это моя оболочка для Camera класса из API)

  Bitmap GetRefImage(PtCamera cam)
    {

        Bitmap image = new Bitmap(2560, 1920, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

        if (cam.IsConnected)
        {
           cam.FetchImage(out image);
        }
        else
        {
           ErrorOccurred?.Invoke(this, $"GetRefImage: {cam.Error}");
        }
        
        return image;
    }
 

В этом контексте я могу получить доступ к растровому изображению и обработать его так, как мне нравится.

После передачи растрового изображения, когда представление закрыто:

 void CloseZoomedView(bool isConf)
    {
        if (cam is object amp;amp; cam.IsConnected)
            cam.Close();
        ZoomClosingArgs eArg = new ZoomClosingArgs()
        {
            IsConfirmed = isConf,
            RefImage = refImage,
        };
        ClosingZoom?.Invoke(this, eArg);
    }
 

Исключение возникает непосредственно при доступе к данным в другой модели представления:

 void HandleZoomImageClosed(object sender, ZoomClosingArgs e)
{
    if (e is object amp;amp; e.IsConfirmed)
    {
        Color test = e.RefImage.GetPixel(0, 0);
        //...
    }
 }
 

Растровое изображение создается путем доступа к памяти камеры через FetchImage()

    public void FetchImage(out Bitmap image)
   {
      camera.Memory.GetActive(out int memID);
      camera.Memory.ToBitmap(memID, out image);
   }
 

Если я заменю код FetchImage() только новым растровым изображением из файла

 image = new Bitmap(@"d:testimage.png")
 

Он работает без проблем в любом контексте.

В документации по API просто говорится следующее:

Доступный

Камера.Память.ToBitmap

Синтаксис

Уйе.Память.ToBitmap(int s32MemId, выход из системы.Рисование.Растровое изображение растровое изображение)

Описание

Возвращает растровое изображение, содержащее изображение. Метод использует уже выделенную память изображения, и изображение отображается в формате, указанном вами при выделении памяти изображения.

Любые намеки очень ценятся.

Комментарии:

1. Как примечание, public void FetchImage(out Bitmap image) это своего рода странный API. Обычно вы объявляете метод как public Bitmap FetchImage() и возвращаете растровое изображение, как вы это делаете в GetRefImage . Обратите также внимание, что инициализация bitmap переменной в GetRefImage бессмысленна. Начальное растровое изображение никогда не используется.

2. @Клеменс: Да, я адаптировал его для этого поста. Фактически, метод FetchImage() возвращает bool, указывающий, возвращали ли методы камеры правильное состояние.

Ответ №1:

Я слишком рано закрыл объект своей камеры. В CloseZoomedView() этом cam.Close() методе освобождаются все области памяти, занятые камерой. При передаче нового растрового изображения перед закрытием оно работает как заклинание.

 void CloseZoomedView(bool isConf)
{        
     ZoomClosingArgs eArg = new ZoomClosingArgs()
     {
        IsConfirmed = isConf,
        RefImage = new Bitmap(refImage),
     };
     
     if (cam is object amp;amp; cam.IsConnected)
        cam.Close();

     ClosingZoom?.Invoke(this, eArg);
 }