【问题标题】:C# AccessViolationException with multiple picturebox zoom and pan sync [WinForms]具有多个图片框缩放和平移同步的 C# AccessViolationException [WinForms]
【发布时间】:2017-09-23 05:49:53
【问题描述】:

我目前正在使用 EmguCV 对图像应用一些过滤器,所以我有 6 个图片框,每个图片框代表相同的图像,但带有一个过滤器。问题是当平移和缩放时有时我得到 AccessViolationException 错误。

    /// <summary>
    /// Start processing the image
    /// </summary>
    public void ProcessImage()
    {
        //Load the image from file and resize it for display
        Image<Bgr, Byte> img =
            new Image<Bgr, byte>(FilePath);
        AddImageBox("Original", img.Bitmap);
        //.Resize(400, 400, Emgu.CV.CvEnum.Inter.Linear, true);

        HistogramPanel.ClearHistogram();
        HistogramPanel.GenerateHistograms(img, 256);
        HistogramPanel.Refresh();

        ListViewItem item = lvData.Items.Add("FileName");
        item.SubItems.Add(FileName);

        item = lvData.Items.Add("Size");
        item.SubItems.Add($"{img.Bitmap.Size.Width}, {img.Bitmap.Size.Height}");




        //Convert the image to grayscale and filter out the noise
        Image<Gray, Byte> imgGray = img.Convert<Gray, Byte>().PyrDown().PyrUp();
        /*UMat uimage = new UMat();
        CvInvoke.CvtColor(img, uimage, ColorConversion.Bgr2Gray);

        //use image pyr to remove noise
        UMat pyrDown = new UMat();
        CvInvoke.PyrDown(uimage, pyrDown);
        CvInvoke.PyrUp(pyrDown, uimage);*/
        AddImageBox("Filtered", imgGray.Bitmap);

        /*Image<Gray, Byte> imgGray =
            new Image<Gray, byte>(uimage.Bitmap);*/
        Image<Gray, Byte> imgCanny = imgGray.Canny(200, 100);
        AddImageBox("Canny", imgCanny.Bitmap);

        Image<Gray, float> imgSobel = imgGray.Sobel(1, 0, 5);
        AddImageBox("Sobel", imgSobel.Bitmap);

        Image<Gray, float> imgLaplace = imgGray.Laplace(3);
        AddImageBox("Laplace", imgLaplace.Bitmap);

        Image<Gray, float> imgSobelHeavy = imgGray.Sobel(0, 1, 3).Add(imgGray.Sobel(1, 0, 3)).AbsDiff(new Gray(0.0));
        AddImageBox("Sobel Heavy", imgSobelHeavy.Bitmap);

        IsLoaded = true;
    }

每个图片框都与其他图片框同步,因此如果缩放或平移,其他图片框将同步到相同的位置并缩放

ImageBox.ZoomChanged += (sender, args) => SyncImages(); ImageBox.Scroll += (sender, args) => SyncImages();

        /// <summary>
    /// Sync all images to be at same zoom and position
    /// </summary>
    public void SyncImages()
    {
        if (ReferenceEquals(ParentTab, null) || ParentTab.SuspendEvents) return;
        ParentTab.SuspendEvents = true;
        foreach (var ctrlImageBox in ParentTab.ImageBoxs)
        {
            if (ReferenceEquals(ctrlImageBox, this))
                continue;

            ctrlImageBox.ImageBox.Zoom = ImageBox.Zoom;
            ctrlImageBox.ImageBox.AutoScrollPosition = new Point(Math.Abs(ImageBox.AutoScrollPosition.X), Math.Abs(ImageBox.AutoScrollPosition.Y));
        }

        Program.FrmMain.UpdateStatusBar();
        ParentTab.SuspendEvents = false;
    }

在平移或缩放后会显示此错误:

发生 System.AccessViolationException H结果=0x80004003 Message=Tentativa de ler ou escrever na memória protegida。 Isto é normalmente uma indicação de que existe outra memória danificada。 源 = System.Drawing 堆栈跟踪: 在 System.Drawing.SafeNativeMethods.Gdip.GdipDrawImageRectRect(HandleRef graphics, HandleRef image, Single dstx, Single dsty, Single dstwidth, Single dstheight, Single srcx, Single srcy, Single srcwidth, Single srcheight, Int32 srcunit, HandleRef imageAttributes, DrawImageAbort 回调, HandleRef 回调数据) 在 System.Drawing.Graphics.DrawImage(图像图像,RectangleF destRect,RectangleF srcRect,GraphicsUnit srcUnit) 在 Cyotek.Windows.Forms.ImageBox.DrawImage(图形 g) 在 Cyotek.Windows.Forms.ImageBox.OnPaint(PaintEventArgs e) 在 System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e,Int16 层) 在 System.Windows.Forms.Control.WmPaint(消息和 m) 在 System.Windows.Forms.Control.WndProc(消息和 m) 在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

我正在使用 AppDomain.CurrentDomain.UnhandledException 来解决这个问题

.NET 框架:4.6.2(带 WinForms)

问题:AccessViolationException

正在使用的图片框:Cyotek.Windows.Forms.ImageBox,也尝试了 Emgu.CV.UI.PanAndZoomPictureBox,我得到了同样的错误

内存看起来像损坏了,或者可能是 GC?

【问题讨论】:

    标签: c# winforms exception emgucv gdi


    【解决方案1】:

    我在同一个视频文件上只使用了两次 VideoCapture 也遇到过类似的问题。

    虽然我不知道确切原因,但这是一个并发问题,适当地使用 lock statements 通常是解决方案。

    我认为两个 VideoCapture 实例在后台都有一些异步代码,当下一个 VideoCapture 实例尝试访问硬盘驱动器上视频文件存储中的同一位置时,这些代码仍在运行。

    这不是一个完整的修复,但将项目编译为 64 位将减少这些问题的频率。我确信这是由于代码在 64 位中运行效率更高,而不是一些迂回的 dll 问题。

    如果我找到完整的解决方案,我一定会通知您。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-01
      • 2010-10-19
      相关资源
      最近更新 更多