入れ方がわかりませんが、頑張ります。
Webカメラを使用して正常に動作するユーザーの写真を撮るWindowsフォームアプリケーションがあります。ここhttp://directshownet.sourceforge.net/にあるdirectshownetライブラリを使用しており、DxSnapサンプルを使用して写真を撮っています。 。
アプリケーションの次の部分では、RFIDタグリーダーを使用します。このリーダーは、タグがスキャンされると、写真を撮るメソッドを呼び出します。また、RFIDリッスンメソッドはGUIスレッドとは別のスレッドで実行されるため、問題が発生します。これは、無限のwhileループであるためです。
写真を撮るために使用されるクラスは、メインスレッドで作成されたコンストラクターのパラメーターとしてpictureboxコントロールのインスタンスを取りますが、これが問題であると思います。
アプリケーションの各部分は個別に正常に動作しますが、リスナースレッドから写真を取得するためにメソッドを呼び出そうとすると、すべての地獄が解き放たれ、アプリがクラッシュします。
メインスレッド(写真を撮る)で初期化されたオブジェクトのメソッドをリスナースレッドから呼び出す方法を知っている人はいますか?
デリゲートと呼び出しを試しましたが、コントロールを直接操作したくないので理解できませんが、メインスレッドでオブジェクトに実行させます。
ここにいくつかのコードがあります:
private Capture cam;
private int portIndex = -1;
private ArrayList AlreadyOpenPortList = new ArrayList();
private byte readerAddr = 0;
private Thread listenThread;
IntPtr m_ip = IntPtr.Zero;
public podiumForm()
{
InitializeComponent();
// scanner and camera startup
startCam();
openComs();
openRF();
startListening();
}
private void startListening()
{
listenThread = new Thread(new ThreadStart(this.Listen));
listenThread.Start();
}
/// <summary>
/// Method of retrieving code tag details from reader
/// </summary>
private void Listen()
{
int fCmdRet = 0x30;
byte state = 1;
byte AFI = 00;
byte[] DSFIDAndUID = new byte[9];
byte cardNumber = 0;
string strDSFIDAndUID = "";
byte outputSet;
if (!GetCurrentUsePort())
{
MessageBox.Show("Open ComPort, Please");
return;
}
while (true)
{
fCmdRet = StaticClassReaderA.Inventory(ref readerAddr, ref state, ref AFI, DSFIDAndUID, ref cardNumber, portIndex);
if (fCmdRet == 0)
{
outputSet = 0;
fCmdRet = StaticClassReaderA.SetGeneralOutput(ref readerAddr, ref outputSet, portIndex);
strDSFIDAndUID = ByteArrayToHexString(DSFIDAndUID).Replace(" ", "");
outputSet = 3;
fCmdRet = StaticClassReaderA.SetGeneralOutput(ref readerAddr, ref outputSet, portIndex);
SavePic(strDSFIDAndUID.Substring(2, 16));
//MessageBox.Show(strDSFIDAndUID.Substring(2, 16));
//ShutDown();
}
}
}
private void SavePic(string text)
{
Cursor.Current = Cursors.WaitCursor;
// Release any previous buffer
if (m_ip != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(m_ip);
m_ip = IntPtr.Zero;
}
// here's where it crashes
// capture image
m_ip = cam.Click();
Bitmap b = new Bitmap(cam.Width, cam.Height, cam.Stride, PixelFormat.Format24bppRgb, m_ip);
cam.Dispose();
// If the image is upsidedown
b.RotateFlip(RotateFlipType.RotateNoneFlipY);
pbPic.Image = b;
Cursor.Current = Cursors.Default;
MessageBox.Show("Here " + text);
}
private void startCam()
{
const int VIDEODEVICE = 0; // zero based index of video capture device to use
const int VIDEOWIDTH = 640; // Depends on video device caps
const int VIDEOHEIGHT = 480; // Depends on video device caps
const int VIDEOBITSPERPIXEL = 24; // BitsPerPixel values determined by device
cam = new Capture(VIDEODEVICE, VIDEOWIDTH, VIDEOHEIGHT, VIDEOBITSPERPIXEL, pbPic);
}
// method in capture class
public IntPtr Click()
{
int hr;
// get ready to wait for new image
m_PictureReady.Reset();
m_ipBuffer = Marshal.AllocCoTaskMem(Math.Abs(m_stride) * m_videoHeight);
try
{
m_WantOne = true;
// If we are using a still pin, ask for a picture
if (m_VidControl != null)
{
// CRASHES HERE with : System.InvalidCastException was unhandled
// Tell the camera to send an image
hr = m_VidControl.SetMode(m_pinStill, VideoControlFlags.Trigger);
DsError.ThrowExceptionForHR(hr);
}
// Start waiting
if (!m_PictureReady.WaitOne(9000, false))
{
throw new Exception("Timeout waiting to get picture");
}
}
catch
{
Marshal.FreeCoTaskMem(m_ipBuffer);
m_ipBuffer = IntPtr.Zero;
throw;
}
// Got one
return m_ipBuffer;
}