‘VS2008’ タグのついている投稿

VS2008で単体テスト

2008 年 12 月 7 日 日曜日

VisualStudio2008 professionalからIDE標準で単体テスト機能(ブラックボックステスト)が付いているので使ってみた。
俺は今まで単体テストはRSpecぐらいしかやったことがなかったし、何かライブラリを作った時はそれを使うGUI付きサンプルアプリケーションを作ることでしか動作確認してこなかったけど、これは次回からどんどん使っていく事にした。

この種のテストをブラックボックステストと呼ぶらしい。テスト対象のクラスの関数1つずつをブラックボックスと見るテストで、入出力の値に注目する。ある値を関数に入れてみて、予想した値が返ってくるかチェックすることで、関数が仕様を満たしているかチェックする。

今回はBenchmarkCounter.NETの中の処理時間を計るためのOrg.Shokai.Util.Benchmark.Counterクラスのテストを作った。Startメソッドで計測開始し、Stopメソッドで停止、その間の処理時間をミリ秒で保存できる。Start/Stopを複数回行った場合、その間の平均処理時間も求める事が出来る。

テストでは、出力値が正しい値になっているかどうかチェックする。このBenchmarkCounterのテストでは

  • 処理時間を取得するメソッドの場合
    → 時間の値が0以上でなければエラー
  • 計測回数を取得するメソッドの場合
    → 何回か計測してみて、計測回数が合わなければエラー
  • 計測中かどうか?フラグの場合
    → Startメソッドにfalseだったらエラー
    → Stopメソッド後にtrueだったらエラー
という感じ。

(続きを読む…)

条件付きコンパイルシンボルで実行ファイルを色々作る

2008 年 6 月 20 日 金曜日

VisualStudioではコンパイル時にコンパイラに渡す定数を定義しておいて、コード上のプリプロセッサで実行ファイルにその部分を含めるか定義する事が出来る事をさっき知った。

こういうコードだと、定数ZANMAIが定義されていればざんまい!!されていなければかず助になる。実行中に条件分岐するのではなく、実行ファイルに丸ごと含まれるか/含まれないかが、コンパイル構成プロファイル毎に変化する。#if ZANMAI

    MessageBox.Show(”ざんまい!!”);

#else

    MessageBox.Show(”かず助!!!!”);

#endif

構成プロファイル「NIKU」を新規作成する。

構成マネージャ

プロジェクトのプロパティのビルドで、条件付きコンパイルシンボルをNIKUプロファイル固有の定数として追加しておく

条件付きコンパイルシンボル

この部分を含んでコンパイルするか、含まない実行ファイルを作るかを解釈するようになる。

動作の違う実行ファイルをそれぞれ書き出せるようになると、それだけ設定画面などを作る必要がなくなるのでうまく使えば便利そう

C#3.0 - DirectShow.NET2.0でwebcam撮影、JPEG保存する

2008 年 6 月 17 日 火曜日

Windowsでカメラからの画像入力を使うには、Flash(Air)Processing、Max/MSPを除くとDirectXかVideo for Windowsを使わなければならないんだけど、これらをC#から直接使うのはとてもめんどい。

で、DirectX自体はラッパーを介して使えるので問題ないんだけど、DirectShow(カメラの入力に使う)だけはなぜかC#用のラッパーが無いのでDirectShow.NETの出番になる。このライブラリはs.h.log » DirectShow.NETで静止画キャプチャでも使ったんだけど、去年ぐらいからDirectShow.NETがver 2.0になってさらに良くなっていた。

ちょっといじってみたが、C++が苦手な馬鹿には便利すぎて感動したので、

webcam撮影→JPEG画像に保存のサンプルを作って置いておきます

■作ったもの

Download (VisualStudio 2008 + C#3.0)

昨日の朝にDirectShow.NET2.0でwebcamキャプチャ、JPEG保存 - 橋本詳解で書いたのとほぼ同じだが、デバイスの選択ができるようになった。

select capture devices

あと、DirectShow.NETを使えば、インストールすると1GBぐらいになるDirectX SDKを入れなくても済むのも嬉しい。

■プログラムの準備

まず準備としてDirectShow.NETのサイトからDirectShowLib-2005.dll本体と、サンプルを手に入れる。

DirectShowLib-2005.dllにパスを通し、sampleに入っているCapture.csもpublic domainなのでコピーしてありがたく使わせていただく。

そして、いくつか使うnamespaceを通す

using DirectShowLib;

using SnapShot;

using System.Runtime.InteropServices;

using System.Drawing.Imaging;

■カメラデバイスを取得してプレビュー表示する

なんでもいいが、System.Windows.Forms.Controlを継承しているPanelやPictureBoxやFormなどを、カメラのプレビュー用に用意しなければならない。プレビューを画面に出したくなければVisible = falseしておけばいい。

そのコントロールをCaptureクラスのコンストラクタに渡してやると、cameraのプレビュー表示がリアルタイムに表示されるようになる。

Panel panelPreview = new Panel();

this.Controls.Add(panelPreview);

Capture cam = new Capture(0, 640, 480, 24, panelPreview); // device, x, y, 24FPS, preview


Capture()の第一引数は画像入力デバイスのindexで、0からはじまる。存在しないデバイスindexを選んでしまうとエラーになるので注意。FPSやカメラのXYサイズも指定できる。

■現在のカメラ表示を保存する

別のコントロールを用意して、そっちに保存する。今回のサンプルアプリの場合は、左の動画が右に静止画としてキャプチャされる。

PictureBoxにキャプチャするなら

PictureBox picBox = new PictureBox();

this.Controls.Add(picBox);

IntPtr m_ip = cam.Click();

Bitmap b = new Bitmap(cam.Width, cam.Height, cam.Stride, PixelFormat.Format24bppRgb, m_ip);

b.RotateFlip(RotateFlipType.RotateNoneFlipY); // 上下反転しているので直す

picBox.Image = b;

Image型で静止画をコピーできたので、JpegファイルやPNGファイルなどに書き出すのも簡単。

picBox.Image.Save("captured.jpg", ImageFormat.Jpeg);

もちろんPictureBoxを経由しないで、直接保存もできる

b.Image.Save("captured.jpg", ImageFormat.Png);

カメラを閉じるのを忘れずに。

FormのFormClosedイベント内などでDispose()を呼べば良い

cam.Dispose();

ちなみに、現在接続してあるデバイスの一覧はDsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice)の中に入っている。

今回のサンプルでコンボボックスの中にデバイス名一覧を突っ込んだのはこんな感じでやった

comboBoxDevices.Items.Clear();

foreach (DsDevice ds in DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice))

{

  comboBoxDevices.Items.Add(ds.Name);

}

comboBoxDevices.SelectedIndex = 0;

ComboBox.SelectedIndexで現在選ばれたデバイス名のindexがわかって、それをCaptureのコンストラクタのデバイスindexとして使えば良い。