全員。私はここで何日もこのバグに対処するために立ち往生していますが、それでもそれを理解することができませんでした。私の推測:オブジェクトを使用した後にオブジェクトを適切に破棄しなかったため、コードに問題があると思います(リソースの解放、スレッド化のこれらの概念についてはあまり詳しくありません)。私はYouTubeで人々が行ったことを参照してこれらのコードを取得しましたが、まったく同じことをしているにもかかわらず、私のコードはうまく機能しませんでした。
状況:2つの画像ボックスがあります。左の1つは私のビデオを撮ることができ、右の1つはスナップショットを撮ることができます。ボタン1を押すと、ビデオが開始され、clone_buttonが画像をコピーします。つまり、スナップショットを撮ります。save_imageはそれをに保存する必要があります。パス参照が、保存しようとしているときにGDI +で何度も一般的なエラーが発生します。また、このプログラムを実行すると、デバッガーがおかしくなったように見えました(つまり、vshost.exeの終了に失敗しました)。コードを再度実行するには、コンピューターを再起動する必要があります。これは、暗くてイライラします。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Drawing.Imaging;
//AForge.Video dll
using AForge.Video;
using AForge.Video.DirectShow;
using AForge.Imaging;
using AForge.Imaging.Filters;
using AForge;
namespace WebCameraCapture
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private FilterInfoCollection CaptureDevice; // list of webcam
private VideoCaptureDevice FinalFrame;
private void Form1_Load(object sender, EventArgs e)
{
CaptureDevice = new FilterInfoCollection(FilterCategory.VideoInputDevice);//constructor
foreach (FilterInfo Device in CaptureDevice)
{
comboBox1.Items.Add(Device.Name);
}
comboBox1.SelectedIndex = 0; // default
FinalFrame = new VideoCaptureDevice();
}
private void button1_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);// click button event is fired,
FinalFrame.Start();
}
void FinalFrame_NewFrame(object sender, NewFrameEventArgs eventArgs) // must be void so that it can be accessed everywhere.
// New Frame Event Args is an constructor of a class
{
pictureBox1.Image = (Bitmap)eventArgs.Frame.Clone();// clone the bitmap
}
private void From1_CLosing(object sender, EventArgs e)
{
if (FinalFrame.IsRunning==true) FinalFrame.Stop();
}
private void save_Click(object sender, EventArgs e)
{
if (pictureBox2.Image != null)
{
Bitmap varBmp = new Bitmap(pictureBox2.Image);
Bitmap newBitmap = new Bitmap(varBmp);
varBmp.Dispose();
varBmp = null;
varBmp.Save(@"C:\a.png", ImageFormat.Png);
}
else
{ MessageBox.Show("null exception"); }
}
private void clone_Click(object sender, EventArgs e)
{
pictureBox2.Image = (Bitmap)pictureBox1.Image.Clone();
}
}
}
AForge.Netユーザーは、下のリンクを押して試してみることができます。ありがとう!
コードを確認したところ、保存する直前に画像を破棄しているように見えます。画像がもう存在しないため、プログラムが画像を保存できないことを意味します。実際には、キャプチャした画像を2回削除したと表示されます。1回目は破棄時、2回目はnullに設定したときです。
したがって、保存後に2つのコードセグメントを移動すると、機能するはずです。ダイアログボックスを使用してファイルの名前を変更せずに付与すると、ファイルが作成されるたびにそのファイルを削除しない限り、必ずエラーが発生します。
private void save_Click(object sender, EventArgs e)
{
if (pictureBox2.Image != null)
{
//Save First
Bitmap varBmp = new Bitmap(pictureBox2.Image);
Bitmap newBitmap = new Bitmap(varBmp);
varBmp.Save(@"C:\a.png", ImageFormat.Png);
//Now Dispose to free the memory
varBmp.Dispose();
varBmp = null;
}
else
{ MessageBox.Show("null exception"); }
}
タスクマネージャを開くと、プログラムがどれだけのメモリを消費しているかを確認できます。使い終わったメモリを廃棄すると、システムに戻されます。 FinalFrame_NewFrameスレッド内にdisposeがないため、カメラが画像を読み取っているときは、プログラムを停止するまでメモリ使用量が増加し続けることがわかります。
スレッドにdisposeを追加して、メモリ使用量を制御しましたが、現在、イメージの保存をデバッグしています。処分しているので画像を保存できません笑。私のプログラムはnull画像ファイルを保存しようとしてしまい、適切なエラーをスローします。
私はあなたと同じように2番目のpicureboxを使用していますが、たとえばpbox2.image = pbox1.imageを使用すると、データはコピーされず、画像データとともにメモリ位置がコピーされるため、pbox1を空きメモリに破棄すると、画像データはメモリ位置とともに消えます。