【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にも連続で出力されている。