我正在制作一个简单的相机,使用Windows窗体在C#中进行3,2,1倒计时,打开一个新窗体以显示捕获的图像。当第一个Form保持空闲状态时,最终会出现错误:“System.Drawing.dll中发生类型'System.InvalidOperationException'的异常,但未在用户代码中处理”。
该程序似乎表明错误是pictureBox1.Image正在其他地方使用:
pictureBox1.Image = (Bitmap)eventArgs.Frame.Clone();
我不确定是什么原因造成的。以下是与相机相关的所有代码:
private static object locker = new Object();
private FilterInfoCollection CaptureDevice;
private VideoCaptureDevice FinalFrame;
public Image File { get; private set; }
public void Form1_Load(object sender, EventArgs e)
{
FormBorderStyle = FormBorderStyle.None;
if (CaptureDevice == null)
{
lock (locker)
{
CaptureDevice = new FilterInfoCollection(FilterCategory.VideoInputDevice);
}
}
foreach (FilterInfo Device in CaptureDevice)
{
lock(locker)
{
comboBox1.Items.Add(Device.Name);
}
}
lock (locker)
{
comboBox1.SelectedIndex = 0;
FinalFrame = new VideoCaptureDevice();
button1.PerformClick();
button2.BringToFront();
}
}
private void button1_Click(object sender, EventArgs e)
{
lock (locker)
{
button1.SendToBack();
FinalFrame = new VideoCaptureDevice(CaptureDevice[comboBox1.SelectedIndex].MonikerString);
FinalFrame.NewFrame += new NewFrameEventHandler(FinalFrame_NewFrame);
FinalFrame.Start();
}
}
private void FinalFrame_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
lock (locker)
{
try
{
pictureBox1.Image = (Bitmap)eventArgs.Frame.Clone(); // <- Here is where the program indicates there is an error
}
catch (Exception exec)
{
Console.Write(exec);
}
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (FinalFrame.IsRunning == true)
{
FinalFrame.Stop();
}
}
private async void button2_Click(object sender, EventArgs e)
{
button2.SendToBack();
button2.Hide();
customLabel1.Show();
await Task.Delay(200);
customLabel1.BringToFront();
customLabel1.Refresh();
await Task.Delay(800);
customLabel1.Refresh();
customLabel1.Text = "2";
await Task.Delay(800);
customLabel1.Refresh();
customLabel1.Text = "1";
await Task.Delay(800);
customLabel1.Refresh();
customLabel1.Text = "3";
customLabel1.Hide();
button2.Show();
button2.BringToFront();
button2.Text = "CAPTURE";
Form2 myPic = new Form2();
myPic.pictureBox1.Image = (Bitmap)pictureBox1.Image.Clone() as Image;
myPic.ShowDialog();
}
答案 0 :(得分:0)
您必须处置以前使用的所有图像。
#pragma once
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <string>
#include <iostream>
#include <list>
void printlist(std::list<std::string> *mylist);
答案 1 :(得分:0)
我遇到了类似的问题。解决方案是仅在UI线程中设置Image
。
因此最佳方法如下所示:
void SetImageThreadSafe(PictureBox pb, Image img)
{
if (pb.InvokeRequired)
{
BeginInvoke((Action) delegate
{
SetImageThreadSafe(pb, img);
});
return;
}
pb.Image?.Dispose();
pb.Image = img;
}