diff --git a/ISCamRecorder/ISCamera.cs b/ISCamRecorder/ISCamera.cs index 49d820b..fc15cd0 100644 --- a/ISCamRecorder/ISCamera.cs +++ b/ISCamRecorder/ISCamera.cs @@ -15,6 +15,7 @@ readonly float FRAME_RATE = 40F; // 設定ファイル無い時のFPS readonly int JPEG_QUALITY = 90; + MainForm _MainForm = null; // メインフォーム ICImagingControl _Cam; // カメラオブジェクト string _SerialNumber; // シリアル番号 string _CamID; // カメラID @@ -22,10 +23,11 @@ FrameRateCounter _Fps = new FrameRateCounter(10); // フレームレート計測 FrameQueueSink _PreviewSink; // プレビューSink FrameQueueSink _RecSink; // 録画Sink + FrameSnapSink _SnapSink; // 静止画Sink SinkListener _SinkListener = new SinkListener(); IFrameQueueBuffer[] _bufferlist = null; // 録画バッファ bool _Recoding = false; // 録画中フラグ - DateTime _RecodingBegin; // 録画開始時間 + //DateTime _RecodingBegin; // 録画開始時間 public float FrameRate { get { return _Fps.FrameRate; } } @@ -34,12 +36,14 @@ /// /// /// - public ISCamera(ICImagingControl cameraControl, string serialNumber) { + public ISCamera(MainForm mf, ICImagingControl cameraControl, string serialNumber) { + _MainForm = mf; _Cam = cameraControl; _SerialNumber = serialNumber; _CamID = $"Cam{_SerialNumber.Substring(_SerialNumber.Length - 2)}"; _RecSink = new FrameQueueSink(_SinkListener, MediaSubtypes.RGB32); _PreviewSink = new FrameQueueSink(CaptureFrame, MediaSubtypes.RGB32, 5); + _SnapSink = new FrameSnapSink(); } /// @@ -97,6 +101,36 @@ } /// + /// 画像撮影 + /// + public void SnapImage() { + TIS.Imaging.FrameSnapSink snapSink = new TIS.Imaging.FrameSnapSink(); + _Cam.LiveStop(); + _Cam.Sink = snapSink; + _Cam.LiveStart(); + + TIS.Imaging.IFrameQueueBuffer frm = snapSink.SnapSingle(TimeSpan.FromSeconds(5)); + var outDir = Path.Combine(_MainForm.OutputBaseDir, "image"); + Directory.CreateDirectory(outDir); + var filename = Path.Combine(outDir, $"{_CamID}_{DateTime.Now.ToString("yyyyMMdd_HHmmss")}.{_MainForm.ImageType.ToLower()}"); + switch (_MainForm.ImageType) { + case "JPG": + frm.SaveAsJpeg(filename, JPEG_QUALITY); + break; + case "BMP": + frm.SaveAsBitmap(filename); + break; + case "TIFF": + frm.SaveAsTiff(filename); + break; + } + + _Cam.LiveStop(); + _Cam.Sink = _PreviewSink; + _Cam.LiveStart(); + } + + /// /// 録画 /// public void RecordToMemory(int framesToCapture) { @@ -106,7 +140,6 @@ // メモリ確保 _RecSink.AllocAndQueueBuffers(framesToCapture); // 撮影 - _RecodingBegin = DateTime.Now; while (_Recoding) { if (framesToCapture <= _RecSink.OutputQueueSize + 1) break; } @@ -136,7 +169,7 @@ for (int i = 0; i < _bufferlist.Length; i++) { writer.Write(_bufferlist[i]); var driverTime = _bufferlist[i].FrameMetadata.DriverFrameFirstPacketTime; - var frameTime = _RecodingBegin.Add(driverTime - firstDriverTime); // パケットをドライバが受信した時刻 + var frameTime = _MainForm.RecodingTime.Add(driverTime - firstDriverTime); // パケットをドライバが受信した時刻 string strSampleTime = frameTime.ToString(@"HHmmss\.fff"); var fileName = $"{_CamID}_{strSampleTime}.{imageType.ToLower()}"; var filePath = Path.Combine(outDir2, fileName); diff --git a/ISCamRecorder/MainForm.Designer.cs b/ISCamRecorder/MainForm.Designer.cs index 4deb50d..3da747e 100644 --- a/ISCamRecorder/MainForm.Designer.cs +++ b/ISCamRecorder/MainForm.Designer.cs @@ -477,7 +477,7 @@ this.BtnSnapImage.Name = "BtnSnapImage"; this.BtnSnapImage.Size = new System.Drawing.Size(74, 27); this.BtnSnapImage.TabIndex = 18; - this.BtnSnapImage.Text = "終了"; + this.BtnSnapImage.Text = "静止画撮影"; this.BtnSnapImage.UseVisualStyleBackColor = true; this.BtnSnapImage.Click += new System.EventHandler(this.BtnSnapImage_Click); // @@ -530,6 +530,7 @@ this.CboImageType.Size = new System.Drawing.Size(52, 20); this.CboImageType.TabIndex = 21; this.CboImageType.Text = "JPG"; + this.CboImageType.SelectedIndexChanged += new System.EventHandler(this.CboImageType_SelectedIndexChanged); // // ChkStartSW // diff --git a/ISCamRecorder/MainForm.cs b/ISCamRecorder/MainForm.cs index 234f6ed..b830c47 100644 --- a/ISCamRecorder/MainForm.cs +++ b/ISCamRecorder/MainForm.cs @@ -55,7 +55,9 @@ public STATE State { get; private set; } = STATE.Init; // ソフトウェアの状態 public DateTime RecodingTime { get; private set; } = DateTime.Now; // 録画開始時間 public string RecodingTimeStr { get { return RecodingTime.ToString("yyyyMMdd_HHmmss"); } } // 録画開始時間文字列 - public string OutputDir { get { return Path.Combine(TxtOutputDir.Text, $"rec{RecodingTimeStr}"); } } // データ保存フォルダ + public string OutputBaseDir { get { return TxtOutputDir.Text; } } // データ保存フォルダ + public string OutputDir { get { return Path.Combine(OutputBaseDir, $"rec{RecodingTimeStr}"); } } // データ保存フォルダ + public string ImageType { get; private set; } /// @@ -77,10 +79,10 @@ SetTitle(this.Text); // カメラ設定 - _Cameras.Add(new ISCamera(icTop, "9220016")); - _Cameras.Add(new ISCamera(icLeft, "9220018")); - _Cameras.Add(new ISCamera(icFront, "9220021")); - _Cameras.Add(new ISCamera(icRight, "9220025")); + _Cameras.Add(new ISCamera(this, icTop, "9220016")); + _Cameras.Add(new ISCamera(this, icLeft, "9220018")); + _Cameras.Add(new ISCamera(this, icFront, "9220021")); + _Cameras.Add(new ISCamera(this, icRight, "9220025")); _Cameras.ForEach(c => c.Connect()); // タイマー&スレッド起動 @@ -89,6 +91,8 @@ _SerialThread = Task.Run(SerialThread); _CvCameraThread = Task.Run(CvCameraThread); + ImageType = CboImageType.Text; + State = STATE.Idle; } @@ -142,7 +146,7 @@ static void UITimerCB(object obj) { if (((MainForm)obj).State == STATE.Exit) return; ((MainForm)obj).UpdateForm(); - ((MainForm)obj).EndRecoding(); + //((MainForm)obj).EndRecoding(); } /// @@ -195,7 +199,12 @@ /// /// private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { - //e.Cancel = true; + if (State == STATE.Idle) { + Task.Run(ExitProgram); + e.Cancel = true; + }else if(State != STATE.Exit) { + e.Cancel = true; + } } /// @@ -265,16 +274,16 @@ StartRecoding(); } + /// + /// 録画開始・中断 + /// public void StartRecoding() { - if (_RecodingThread != null) { - // 中断 - //_Cameras.ForEach(c => c.StopRecoding()); - Debug.WriteLine("recoding"); - } else { - var player = new SoundPlayer(@"start.wav"); - player.Play(); - + if (State == STATE.Idle) { _RecodingThread = Task.Run(RecodingThread); + } else if (State == STATE.Recoding) { + // 中断 + Debug.WriteLine("Stop recoding"); + _Cameras.ForEach(c => c.StopRecoding()); } } @@ -291,7 +300,7 @@ this.Invoke((MethodInvoker)delegate { _Cameras.ForEach(c => c.ChangeSink(true)); - BtnRecodeMovie.Enabled = false; + //BtnRecodeMovie.Enabled = false; BtnSetProperty.Enabled = false; BtnRecodeMovie.Text = "撮影中"; originalButtonColor = BtnRecodeMovie.BackColor; @@ -308,10 +317,12 @@ var imageType = imageTypeTxt; // 録画開始 + var player = new SoundPlayer(@"start.wav"); + player.Play(); RecodingTime = DateTime.Now; Directory.CreateDirectory(OutputDir); State = STATE.Recoding; - //_CvCamera.StartRecoding(); + // 録画 Task[] tasks = new Task[4]; for (var i = 0; i < _Cameras.Count; i++) { @@ -321,7 +332,8 @@ Task.WaitAll(tasks); State = STATE.Saving; - //_CvCamera.StopRecoding(); + player = new SoundPlayer(@"end.wav"); + player.Play(); // 保存 this.Invoke((MethodInvoker)delegate { @@ -354,6 +366,14 @@ /// /// private void BtnSnapImage_Click(object sender, EventArgs e) { + if (State != STATE.Idle) return; + _Cameras.ForEach(c => c.SnapImage()); + } + + /// + /// プログラム終了 + /// + private void ExitProgram() { State = STATE.Exit; _UITimer.Dispose(); @@ -365,7 +385,18 @@ _TriggerThread.Wait(timeout); Debug.WriteLine("_TriggerThread stop"); - this.Close(); + this.Invoke((MethodInvoker)delegate { + this.Close(); + }); + } + + /// + /// 画像形式選択時 + /// + /// + /// + private void CboImageType_SelectedIndexChanged(object sender, EventArgs e) { + ImageType = CboImageType.Text; } } } diff --git a/ISCamRecorder/media/end.wav b/ISCamRecorder/media/end.wav index cab656c..a5160f0 100644 --- a/ISCamRecorder/media/end.wav +++ b/ISCamRecorder/media/end.wav Binary files differ