2013-04-17 10 views
8

Şu anda AForge ile çalışıyorum ve çerçeveyi bir bitmap olarak bir resim kutusunun içine yerleştiren yeni bir çerçeve etkinliğim var. Zamanın% 90'ı harika çalışıyor ... UNLESS Winformda bir şeyle uğraşıyorum. Bir açılan kutu değiştirme penceresini taşımış veya böyle bir şey Picturebox aşağıda büyük bir kırmızı X Kod örneği videodan geçmek için yol açabileceğini: Ben eğer (videoPictureBox1.Image bir mola koyduPicturebox büyük kırmızı X elde ediyor ancak onu tespit edemiyorum ya da düzeltemiyorum

private void connectButton_Click(object sender, EventArgs e) 
    { 
     try 
     { 
      cam = new VideoCaptureDevice(captureDevices[CameraSelectComboBox.SelectedIndex].MonikerString); 
      cam.NewFrame -= Handle_New_Frame; //Just to avoid the possibility of a second event handler being put on 
      cam.NewFrame += new AForge.Video.NewFrameEventHandler(Handle_New_Frame); 
      cam.Start(); 
     } 
     catch 
     { 
      MessageBox.Show("An error has occured with connecting to the specified webcam. The application will now close!"); 
      Application.Exit(); 
     } 
    } 

    private void Handle_New_Frame(object sender, NewFrameEventArgs eventArgs) 
    { 

     try 
     { 
      if (bitmap != null) 
       bitmap.Dispose(); //Without this, memory goes nuts 
      bitmap = new Bitmap(eventArgs.Frame); 
     } 
     catch { } 

     //Draw some stuff on the images 
     bitmap = AdjustBrightness(bitmap, brightnessMeter); 
     bitmap = ApplyContrast(contrastMeter, bitmap); 
     bitmap = Draw_Top_Line(bitmap); 
     bitmap = Draw_Bottom_Line(bitmap); 

     //Set the image into the picturebox 
     this.Invoke((MethodInvoker)delegate 
     { 
      videoPictureBox1.Image = bitmap; 
      frameRate++; //Keep track of the frame rate 
     }); 

     GC.Collect(); //Without this, memory goes nuts 

     this.Invoke((MethodInvoker)delegate { 
      videoPictureBox1.Refresh(); //NOT NECESSARY. JUST TRYING TO FIX THE BIG RED X! 
     }); 

     if (videoPictureBox1.Image == videoPictureBox1.ErrorImage) 
     { 
      cam.Stop(); //ALSO NOT NECESSARY> AGAIN, JUST TRYING TO FIX THE BIG RED X! 
      cam.Start(); 
     } 
    } 

== videoPictureBox1.ErrorImage) ve büyük kırmızı X olduğunda bile false değerini değerlendiriyor, çünkü görüntü aslında bitmap'e ayarlanıyor. Yani cam.Stop() ve cam.Start() asla (bu yardımcı olsa bile emin değilim, ama ben bir deneyin vereceğini düşündüm).

videoPictureBox1.Refresh() her zaman çalışıyor, ancak yine de bir fark yaratmıyor. Hala büyük kırmızı X.

Daha önce de söylediğim gibi: videoyu başlatıp hiçbir şeye dokunmazsam, büyük kırmızı X asla olmayacaktır. Ama açılan kutuları değiştirmeye başladığım ya da formun kendisini sürüklediğimde, büyük kırmızı X'in şansı katlanarak artar. Bazen açılan kutudan 10-12 kez geçebilirim, diğer zamanlarda ise combobox'ı tıklıyorum. : - \

Burada neler olup bittiğini açıklayabilir ve belki de bunu düzeltmek için en iyi yöntem hakkında bir öneri sunabilir mi? Ben hala iş parçacığı için çok yeni, bu yüzden burada neler olup bittiğini ve sorunu düzeltmek için en iyi yolu etrafında kafamı sarmak için mücadele ettik! Doğru yönde herhangi bir dürtü çok büyük bir yardım olurdu!

+1

Sanırım muhtemelen bir resim kutusu kullanmam. Bunun yerine bir panel kullanın ve panelin boya olayındaki bitmapi çizin. Geçersiz kılma ile yenilemek. –

+0

Büyük kırmızı X senario sırasında eventArgs.Frame'e bir göz attınız mı? Ayrıca, hata oluştuğu durumda, bu istisnanın altında bir mesaj kutusu koyardım. – TheKingDave

+0

Pekala, bunu gerçekten hızlı bir şekilde deneyeceğim! Ek not: Hata ayıklama - istisnalara gittim ve tüm "Atılmış" onay kutularını işaretledim. Bu olduğunda hiçbir şey atar. Hiç de. –

cevap

6

, bir Invoke içinde Handle_New_Frame in her şeyi tamamladı. Sürekli olarak büyük kırmızı X sorununu tamamen kaldırdı. > _>

private void Handle_New_Frame(object sender, NewFrameEventArgs eventArgs) 
{ 
    this.Invoke((MethodInvoker)delegate 
    { 
    try 
    { 
     if (bitmap != null) 
     { 
      bitmap.Dispose(); //Without this, memory goes nuts 
     } 

     bitmap = new Bitmap(eventArgs.Frame); 
    } 
    catch { } 

    //Draw some stuff on the images 
    bitmap = AdjustBrightness(bitmap, brightnessMeter); 
    bitmap = ApplyContrast(contrastMeter, bitmap); 
    bitmap = Draw_Top_Line(bitmap); 
    bitmap = Draw_Bottom_Line(bitmap); 

    //Set the image into the picturebox 
    this.Invoke((MethodInvoker)delegate 
    { 
     videoPictureBox1.Image = bitmap; 
     frameRate++; //Keep track of the frame rate 
    }); 

    GC.Collect(); //Without this, memory goes nuts 
    }); 
} 
+0

Aynı şeyle karşılaştım ve neler olduğunu anlamaya çalıştım, boşuna. Sanırım bir tek-iplik politikası var, ama hiçbir istisna ya da hata mesajı alamamış olursam, yaklaşımınıza gittim ve şimdi işe yarıyor. –

+0

Merhaba, onu kullandım ama videoSource'u kapatmaya çalıştığımda durmuyor ve kaynağı serbest bırakmak için beklemiyor ... Aynı problemin var mı? – elle0087

1

Bitmap'i kullandığınız yerlerde klon kullanmayı deneyin. Ör: Sonunda

videoPictureBox1.Image = (Bitmap)bitmap.Clone(); 
+0

Bu aynı zamanda bir yarış koşuluna da yol açabilir veya yanlış mıyım? Bitmap atma ve bitmap'i klonlama arasında bir yeniden çekim gerçekleşirse büyük kırmızı X görünecektir. – Hans

+0

@Hans evet, atmadan önce bitmapi kullanmayı deneyin() – Rsouza

+0

@Hans, cevabımda kodu kontrol edebilir misiniz? Böyle bir yarış durumu oluşturmaya çalıştım ama yapamadım. –

3

Shawn Hargreaves "kıyamet büyük kırmızı X" mükemmel bir özlü writeup sahiptir. WinForm bileşenlerini aniden kırmızı "X" i gösteren genel durum konusunda çok yardımcı buldum. Özetle

:

  • Bu OnPaint olayın üzerinden istisna atan bir kontrol kaynaklanır. o atılır sonra
  • , o kontrolü kırmızı X göstermeye devam ve hata ayıklama için OnPaint.
  • ateş atlamak, ortak dil çalışma zamanı İstisnalar yakalamak için ayıklayıcısını ayarlayın ve sonra normalde kırmızı X almak için ne olursa olsun yapacağız Hata ayıklayıcının olduğu yerde durması, araştırmanızı ve umarız bunu önlemenin bir yolunu bulmanızı sağlar.
0

Sadece özetlemek gerekirse, yeniden boyutlandırıldığında, başlatıldığında, durdurulduğunda veya özünürlüğünde değişiklik yapıldığında bile, benim için hiç bir kırmızı çarpı işareti olmayan test edilmiş bir minimumdur.

public partial class PictureBoxVideo : Form 
    { 
     public PictureBoxVideo() 
     { 
     InitializeComponent(); 
     var videoDevices = new FilterInfoCollection(FilterCategory.VideoInputDevice); 
     var videoSource = new VideoCaptureDevice(videoDevices[0].MonikerString); 
     videoSource.NewFrame += Handle_Very_New_Frame; 
     videoSource.Start(); 
     } 

     private void Handle_Very_New_Frame(object sender, NewFrameEventArgs eventArgs) 
     { 
     this.Invoke((MethodInvoker)delegate { 
      pictureBox.Image = new Bitmap(eventArgs.Frame); 
     }); 
     } 
    } 

VideoSource.Start(); GUI- (oluşturma) -düzeltten, ancak geri arama işleyicisi (Handle_Very_New_Frame) video (worker) iş parçacığı denir.

Bence bu yüzden hem Invoke hem de yeni Bitmap'e ihtiyacımız var, bu yüzden yeni bmp de gui-thread'den üretilecek. Ama ben sadece burada bir tahminde bulunamadığım için tahmin ediyorum.

+0

BTW: Ben bu yaklaşımın son derece hızlı bir şekilde çok hızlı bir şekilde terkedilmesini :-) –

+0

merhaba, kullandım ama videoSource'u kapatmaya çalıştığımda durmuyor ve kaynağı serbest bırakmak için beklemeye devam etmiyor ... aynı problem var mı? – elle0087

İlgili konular