本文介绍了使用AForge和Graphics.FromImage.DrawImage防止OutOfMemoryException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have written a code to allow the user to start and stop a feed from their webcam. I have used AForge.NET's NewFrameEventArgs to update a PictureBox with the new frame each time it changes. Everything works perfectly however whenever I start the feed, the RAM usage on my computer slowly goes up until an OutOfMemoryException occurs.

请您能帮我找出如何清除或清除此问题的方法.当我得到异常时,它发生在ScaleImage的代码底部:

Please could you help me find out how to clear or flush this somehow. When I get the exception, it occurs at the bottom of the code in 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;
        }
    }
}

推荐答案

在添加新的缩放图像之前,您需要处理前一张图像(只要它不为null).

You need to dispose the previous image (as long as it is not null) before you add the new scaled image.

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.)

Question: Is it really necessary to create a clone of the input image? What exactly does eventArgs.Frame reference? (I don't have AForge.)

这篇关于使用AForge和Graphics.FromImage.DrawImage防止OutOfMemoryException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-23 02:22
查看更多