2013-03-21 2 views
0

Я просмотрел несколько страниц похожих запросов, реализовал большинство предложений, но, похоже, не нашел ничего, что сработало до сих пор. Надеюсь, я не упускаю из виду нечто очевидное.C# Ошибка памяти для фотокамер

Правильно, поэтому я использую AForge.net для захвата изображения. Это обеспечивает событие, которое срабатывает для каждого нового кадра, полученного, что в моем коде выглядит следующим образом:

private void videoSourcePlayer_NewFrame(object sender, ref Bitmap image) 
    { 
     framesRecieved++; 
     try 
     { 
      if (!stopCapturing) 
      { 
       if (pictureBox1.Image != null) 
       { 
        pictureBox1.Image.Dispose(); 
       } 
       pictureBox1.Image = image.Clone(new Rectangle(0, 0, image.Width, image.Height), image.PixelFormat); 
      } 

     } 
     catch { } 
     finally { GC.Collect(); } 
    } 

Использование памяти является очень стабильным, пока окно остается неподвижным, но как только я захватить окно формы и начать перемещение, использование памяти продолжает расти. Причина, по которой я был убежден, что это может быть связано с файловым полем, заключается в том, что, как только я перехожу к «stopCapturing» bool в true, память перестает расти, даже если я перемещаю окно по экрану. «stopCapturing» не используется ни для чего другого, и событие продолжает запускаться как обычно, единственное различие заключается в том, что изображение отображается в окне изображения. Я в недоумении относительно причины, поэтому любая помощь будет оценена по достоинству.

PS: Не уверен, что это связано, но на моей рабочей станции есть 2 экрана.

+0

Начните с удаления пустого улова и GC.Collect. –

+1

Не уверен в необходимости «Clone». Я использовал 'new Bitmap (изображение)' без проблем раньше. –

ответ

0

Bitmap.Clone() делает мелкую копию, фактические байты по-прежнему принадлежат вызывающей стороне, поэтому это может потенциально вызвать всевозможные проблемы. Вам нужно сделать глубокую копию.

Например, AForge way:

Bitmap bmp = AForge.Imaging.Image.Clone(image); 

Или GDI + способ (можно также использовать LockBits и т.д. для лучшего perfs):

Bitmap bmp = new Bitmap(image.Width, image.Height, image.PixelFormat); 
Graphics g = Graphics.FromImage(bmp); 
g.DrawImageUnscaled(image, Point.Empty); 
0

мне интересно, почему вы клонировании изображение вообще. Она поражает меня, что вы должны выделить новое изображение только когда либо pictureBox1.Image равна нулю, или когда размеры или пиксельный формат изменения изображения:

private bool BitmapChanged(Bitmap old, Bitmap new) 
{ 
    return old == null || old.PixelFormat != new.PixelFormat || 
     old.Width != new.Width || old.Height != new.Height; 
} 

private Bitmap MakeSimilarBitmap(Bitmap source) 
{ 
    Bitmap copy = new Bitmap(source.Width, source.Height, source.PixelFormat); 
    return copy; 
} 

private void DrawOnto(Image im, Bitmap source) 
{ 
    using (Graphics g = Graphics.FromImage(im)) { 
     g.DrawImage(source, 0, 0); 
    } 
} 

тогда, когда вы получаете кадр, вы будете делать что-то вроде это:

Image im = BitmapChanged(pictureBox1.Image as Bitmap, srcBmp) ? 
          MakeSimilarBitmap(image) : pictureBox1.Image; 
DrawOnto(im, srcBmp); 
bool same = im == pictureBox1.Image; 
if (same) 
    pictureBox1.Invalidate(); 
else { 
    Image old = pictureBox1.Image; 
    pictureBox1.Image = im; 
    old.Dispose(); 
} 
+0

Вам нужно сделать копию, потому что изображение принадлежит VideoSource. Он будет распоряжаться по своему усмотрению. См. Также: http://www.aforgenet.com/framework/docs/html/63e8ac47-e9c1-d257-c587-c995c5a99b3f.htm –

+0

Я хочу сказать, что вы копируете содержимое в один сохраненный битмап, а не выделяете новую копию каждый рама. – plinth

Смежные вопросы