【C#】CSharpWinForms開発Webカメラで二次元コード読取り&Excel出力
ツール画面
二次元コードをWebカメラから読取り、リアルタイムにExcelに出力できるツールを作ってみた。


ソースコード
今回のアプリケーションの参照ライブラリは下記の画像の通りとなってます。各自Nugetからインストールして追加して下さい。

それでは、ソースコードは下記の通りとなります。
using log4net; using Microsoft.Office.Interop.Excel; using OpenCvSharp; using OpenCvSharp.Extensions; using System; using System.ComponentModel; using System.Drawing; using System.Runtime.InteropServices; using System.Threading.Tasks; using System.Windows.Forms; using ZXing; using Excel = Microsoft.Office.Interop.Excel; namespace QR_reader_Excel_out_rev1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } //ログ出力用 public ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); //ログ出力用 private bool qrresult = true; public int camera_device_num = 0; public string result_str; public int sleep_time; //アプリケーションのオブジェクト public Excel.Application excel; //ブックのオブジェクト public Workbook workbook; //シートのオブジェクト public Worksheet Sheet; public Excel.Range rangefor_brank; public Excel.Range range_select; /// <summary> /// 画面起動 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form1_Load(object sender, EventArgs e) { logger.Info("☆起動!"); sleep_time_txt.Text = Properties.Settings.Default.Sleep_time_txt; sleep_time = int.Parse(sleep_time_txt.Text); //ボタン非表示 restart_btn.Visible = false; // backgroundWorker1.RunWorkerAsync(); } private void BackgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { using (VideoCapture capture = new VideoCapture(camera_device_num)) { using (Mat normalframe = new Mat()) //無限ループ while (qrresult == true) { //キャプチャ読込 capture.Read(normalframe); if (!normalframe.Empty()) { // 新しい画像を取得したので、 // ReportProgressメソッドを使って、ProgressChangedイベントを発生させる //this.backgroundWorker1.ReportProgress(0, normalframe); //画像表示 pictureBox.Image = normalframe.ToBitmap(); //画像処理QRコード //コードの解析 BarcodeReader reader = new BarcodeReader(); reader.Options = new ZXing.Common.DecodingOptions { PossibleFormats = new[] { BarcodeFormat.All_1D, BarcodeFormat.QR_CODE, BarcodeFormat.DATA_MATRIX } }; reader.AutoRotate = true; //90度ずつ回転させて読取 reader.TryInverted = true; //読み取れなかったときに白黒反転。デコードが遅くなるので注意 reader.Options.TryHarder = true; //ビットマップをよりDeepに解析 //QRコードのデコーダ処理 Result result = reader.Decode(normalframe.ToBitmap()); if (result != null) { //バックグラウンド処理1 プログレス更新時 this.backgroundWorker1.ReportProgress(0, result); } } } } } private void BackgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e) { qrresult = false; //QR読取結果の引数を取得 ZXing.Result result = (ZXing.Result)e.UserState; result_str = result.Text; barcodeFormatBox.Text = result.BarcodeFormat.ToString(); //二次元コード種別表示 readResultBox.Text = result_str; //内容表示 readResultBox.BackColor = Color.LightGreen; } private void BackgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { //履歴表示 if (result_str != "") { logger.Info("読取内容履歴表示:" + result_str); out_report.Focus(); out_report.AppendText(result_str + "\n"); } //ボタン表示 restart_btn.Visible = true; //背景色変更 readResultBox.BackColor = Color.LemonChiffon; if (result_str != "") { //バックグラウンド処理2実行 this.backgroundWorker2.RunWorkerAsync(); } //テキストボックスの中身をクリア barcodeFormatBox.Text = string.Empty; readResultBox.Text = string.Empty; //*秒間待機させる System.Threading.Thread.Sleep(sleep_time); // BackgroundWorkerが処理中でなければ if (!backgroundWorker1.IsBusy) { qrresult = true; backgroundWorker1.RunWorkerAsync(); } } /// <summary> /// Excel出力 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void BackgroundWorker2_DoWork(object sender, DoWorkEventArgs e) { Task.Run(() => Invoke(new System.Action(Write_excel))); } /// <summary> /// 読取再開ボタン押下 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Restart_btn_Click(object sender, EventArgs e) { // BackgroundWorkerが処理中でなければ if (!backgroundWorker1.IsBusy) { qrresult = true; backgroundWorker1.RunWorkerAsync(); } } /// <summary> /// 履歴クリアボタン押下 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void History_clear_btn_Click(object sender, EventArgs e) { out_report.Clear(); } /// <summary> /// カメラ切替ボタン押下 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Camera_change_btn_Click(object sender, EventArgs e) { qrresult = false; backgroundWorker1.CancelAsync(); if (camera_device_num == 0) { camera_device_num = 1; } else { camera_device_num = 0; } // BackgroundWorkerが処理中でなければ if (!backgroundWorker1.IsBusy) { qrresult = true; // バックグラウンド処理を開始 backgroundWorker1.RunWorkerAsync(); } } /// <summary> /// 書込み新規ファイル作成 /// </summary> public void Write_excel() { if (checkBox1.Checked) { try { rangefor_brank = Sheet.Range["A1"]; //セル選択 range_select = rangefor_brank.Offset[1, 0]; // 1行下のセルに書込み //初回セルA2が空欄ならセルA2に代入 if (range_select.Value == "") { range_select.Value = result_str; //二次元コード内容書込み } //セルA2が埋まっていれば、その1つ下の行に代入 else { Excel.Range end_rows = Sheet.Range["A1048576"]; //最終行 Excel.Range cell_select = end_rows.End[Excel.XlDirection.xlUp]; //上にいって使用最終行 Excel.Range cell_value_write = cell_select.Offset[1, 0]; //オフセットで1つ下の行 cell_value_write.Value = result_str; } } catch (Exception e) { logger.Error("Excel書込み:エラー:" + e.Message); MessageBox.Show("Excel書込み:エラー:" + e.Message); } finally { // アプリケーションのオブジェクトの解放 Marshal.ReleaseComObject(excel); GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); } } } /// <summary> /// 画面閉じる時 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Form1_FormClosing(object sender, FormClosingEventArgs e) { Properties.Settings.Default.Sleep_time_txt = sleep_time_txt.Text; Properties.Settings.Default.Save(); } /// <summary> /// チェックボックスが押下したイベント /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void CheckBox1_CheckedChanged(object sender, EventArgs e) { //アプリケーションのインスタンス作成 excel = new Excel.Application { //アプリケーションの表示 Visible = true }; // ファイル新規オープン workbook = excel.Workbooks.Add(); Sheet = workbook.Sheets[1]; //シート[1]:左端のシート } } }が
画面デザイン
画面設計は下記の通りです。

出力機能
- 1.履歴としてテキストボックスに出力し、残せる。
- 2.Excelに出力できる。
- 3.logファイルで残せる。
1.履歴欄に読み取った結果内容を出力していくので、Excel使用しなくてもすぐに読取結果を使用できる。
2.Excelに出力もできるので、読み取ったら、Excel上ですぐに結果を編集できる。
3.log4netの設定をしておけば、気にせず、logファイルを残せるので、過去の読取結果も見れる。
サンプル
QRコード5個用意して連続で読み取った結果、Excelにも連続で出力されている。
