【问题标题】:Prevent OutOfMemoryException With AForge and Graphics.FromImage.DrawImage使用 AForge 和 Graphics.FromImage.DrawImage 防止 OutOfMemoryException
【发布时间】:2015-01-03 19:30:26
【问题描述】:

我编写了一个代码,允许用户从他们的网络摄像头开始和停止供稿。我已经使用 AForge.NET 的 NewFrameEventArgs 来在每次更改时使用新框架更新 PictureBox。一切正常,但是每当我启动提要时,我计算机上的 RAM 使用率就会缓慢上升,直到发生 OutOfMemoryException。

请您帮我找出如何以某种方式清除或冲洗它。当我得到异常时,它发生在 ScaleImage 代码的底部:

System.Drawing.Graphics.FromImage(newScaledImage).DrawImage(image, 0, 0, newWidth, newHeight);

到目前为止我的代码:

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;
using AForge.Video;
using AForge.Video.DirectShow;

namespace WebCameraCapture
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private VideoCaptureDevice FinalFrame;
        System.Drawing.Bitmap fullResClone;

        void FinalFrame_NewFrame(object sender, NewFrameEventArgs eventArgs)
        {
            pictureBox1.Image = ScaleImage((Bitmap)eventArgs.Frame.Clone(), 640, 480);
        }

        private void btn_startCapture_Click(object sender, EventArgs e)
        {
            FinalFrame = new VideoCaptureDevice(CaptureDevice[comboBox1.SelectedIndex].MonikerString);//Specified web cam and its filter moniker string.
            FinalFrame.NewFrame += new NewFrameEventHandler(FinalFrame_NewFrame);
            FinalFrame.Start();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            CaptureDevice = new FilterInfoCollection(FilterCategory.VideoInputDevice);
            foreach (FilterInfo Device in CaptureDevice) { comboBox1.Items.Add(Device.Name); }

            comboBox1.SelectedIndex = 0; //Default index.
            FinalFrame = new VideoCaptureDevice();
        }

        //This ScaleImage is where the OutOfMemoryException occurs.
        public static System.Drawing.Image ScaleImage(System.Drawing.Image image, int maxWidth, int maxHeight) //Changes the height and width of the image to make sure it fits the PictureBox.
        {
            var ratioX = (double)maxWidth / image.Width;
            var ratioY = (double)maxHeight / image.Height;
            var ratio = Math.Min(ratioX, ratioY);

            var newWidth = (int)(image.Width * ratio);
            var newHeight = (int)(image.Height * ratio);

            var newScaledImage = new Bitmap(newWidth, newHeight);
            System.Drawing.Graphics.FromImage(newScaledImage).DrawImage(image, 0, 0, newWidth, newHeight); // <<<< RIGHT HERE
            return newScaledImage;
        }
    }
}

【问题讨论】:

  • 每次有一个新的图形对象被创建到内存中,也许你可以尝试在分配一个新的对象后将之前的对象处理掉。
  • 是的,您应该处理图形对象,可能是您从 AForge 获得的对象,也可能是您在 ScaleImage 方法中创建的对象。
  • 我是处理对象的新手,你能给我举个例子说明如何实现这个,把它放在哪里,放什么等等。

标签: c# winforms out-of-memory webcam aforge


【解决方案1】:

在添加新的缩放图像之前,您需要处理之前的图像(只要它不为空)。

void FinalFrame_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
    if (pictureBox1.Image != null) { pictureBox1.Image.Dispose(); }

    Bitmap tempBitmap = (Bitmap)eventArgs.Frame.Clone();
    pictureBox1.Image = ScaleImage(tempBitmap, 640, 480);
    tempBitmap.Dispose();
}

问题:真的有必要创建输入图像的克隆吗? eventArgs.Frame 到底指的是什么? (我没有 AForge。)

【讨论】:

  • 非常感谢,这似乎已经解决了这个问题。我是 AForge 的新手,我真的不知道为什么需要克隆框架,但它与需要它的 AForge dll 有关...
  • 克隆图像是必要的,因为它的内存归 AForge 所有。当事件处理程序返回时,AForge 将自行决定Dispose 它,您最终会得到一个无效的位图。
  • 这仍然没有Dispose() GraphicsSystem.Drawing.Graphics.FromImage(newScaledImage) 中返回的对象 ScaleImage 方法(只是位图)。这最终也会遇到问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-27
  • 1970-01-01
  • 2011-08-06
  • 2013-05-18
  • 1970-01-01
  • 2013-04-06
相关资源
最近更新 更多