【问题标题】:Bitmap access violation exception with camera image相机图像的位图访问冲突异常
【发布时间】:2021-09-10 08:03:10
【问题描述】:

在我的 WPF 应用程序中,图像是使用相机拍摄的,使用视图,然后在通过 eventargs 关闭时作为位图传递给另一个。但是,当我尝试处理图像时,我得到了 AccessViolationException。当我在传递图像之前处理图像或使用从文件加载的图像时,不会发生这种情况。

从相机获取图像(PtCamera 类是我对 API 中的 Camera 类的封装)

 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 && cam.IsConnected)
            cam.Close();
        ZoomClosingArgs eArg = new ZoomClosingArgs()
        {
            IsConfirmed = isConf,
            RefImage = refImage,
        };
        ClosingZoom?.Invoke(this, eArg);
    }

访问其他viewmodel中的数据时直接发生异常:

void HandleZoomImageClosed(object sender, ZoomClosingArgs e)
{
    if (e is object && 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 文档简单说明如下:

无障碍

Camera.Memory.ToBitmap

语法

uEye.Memory.ToBitmap(int s32MemId, out System.Drawing.Bitmap bitmap)

说明

返回包含图像的位图。该方法使用已经 分配的图像内存,图像以您的格式显示 分配图像内存时指定。

非常感谢任何提示。

【问题讨论】:

  • 请注意,public void FetchImage(out Bitmap image) 是一种奇怪的 API。您通常会将该方法声明为public Bitmap FetchImage() 并返回位图,就像您在GetRefImage 中所做的那样。另请注意,GetRefImage 中 bitmap 变量的初始化是没有意义的。从不使用初始位图。
  • @Clemens:是的,我为这篇文章改编了它。实际上,FetchImage() 方法返回一个布尔值,指示相机方法是否返回正确的状态。

标签: c# wpf bitmap camera eventargs


【解决方案1】:

我过早地关闭了我的相机对象。在CloseZoomedView() 中,cam.Close() 方法会释放相机占用的所有内存区域。在关闭之前传递一个新的位图就像一个魅力。

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

     ClosingZoom?.Invoke(this, eArg);
 }

【讨论】:

    猜你喜欢
    • 2021-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-01
    相关资源
    最近更新 更多