Предотвратить исключение OutOfMemoryException с помощью AForge и Graphics.FromImage.DrawImage
Я написал код, позволяющий пользователю запускать и останавливать канал со своей веб-камеры. Я использовал AFF.NET NewFrameEventArgs для обновления PictureBox с новым кадром каждый раз, когда он изменяется. Все работает отлично, однако всякий раз, когда я запускаю канал, использование оперативной памяти на моем компьютере постепенно увеличивается, пока не возникнет исключение 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;
}
}
}
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.)