2015年11月7日土曜日

完成:とりあえず、カメラのシャッターをパソコンで押してみよう。

◆前回までのブログで、パソコンからカメラを制御して、画像を取り込むまでのプログラムの説明は一通り済みましたので、メインとなるコード(Form1.cs)全体を貼り付けておきます。
using System;
using System.Windows.Forms;
using System.IO;

using Nikon;

namespace WindowsFormsApplication1 {

      public  partial  class  Form1  :  Form  {
            private  NikonManager  nknManager;
            private  NikonDevice  nknDevice;
           
                  public  Form1()  {
                        InitializeComponent();

                        //  ニコンマネージャーの初設定("Type00**.md3"は、機種によって異なる。)
                        nknManager  =  new  NikonManager("Type0011.md3");
                        nknManager.DeviceAdded  +=  new  DeviceAddedDelegate(manager_DeviceAdded);
                        nknManager.DeviceRemoved  +=  new  DeviceRemovedDelegate(manager_DeviceRemoved);
                  }

                  private  void  button1_Click(object  sender,  EventArgs  e)  {
                        if  (nknDevice  ==  null)  {
                              return;
                        }

                        try  {
                              nknDevice.Capture();
                        }  catch  (NikonException  ex)  {
                              MessageBox.Show(ex.Message);
                  }
            }

              //デバイス接続時のイベントで呼び出されるメソッドです。
            void  manager_DeviceAdded(NikonManager  sender,  NikonDevice  device)  {
                  this.nknDevice  =  device;

                  //ラベルにデバイスネーム(カメラの種類:ここでは、”D5300”と表示される。)
                  label1.Text  =  device.Name;

                    //  シャッターが押されて、撮影画像が準備出来たら呼び出されるメソッドを登録
                    device.ImageReady  +=  new  ImageReadyDelegate(device_ImageReady);
            }

            //デバイス切断時のイベントで呼び出されるメソッドです。
            void  manager_DeviceRemoved(NikonManager  sender,  NikonDevice  device)  {
                  this.nknDevice  =  null;
            }

            //撮影画像がイメージバッファに準備出来た時に発火する(呼び出される)メソッドです。
            void  device_ImageReady(NikonDevice  sender,  NikonImage  image)  {
                  //ここで、ファイルに保存しています。
                  using  (FileStream  stream  =  new  FileStream("Image1.jpg",  FileMode.Create,  FileAccess.Write))  {
                        stream.Write(image.Buffer,  0,  image.Buffer.Length);
                  }
            }
      }
}

その2:とりあえず、カメラのシャッターをパソコンで押してみよう。

◆前回の追加

5. "ソリューションプラットホーム"を"x86"にする。

 前回の設定の追加です。手順「3.」で、プラットホームターゲットを"Any CPU"から、"x86"に変更しましたが、ソリューションプラットホームも同様に変更しておきます。















6. フォームに、ボタンとラベルコントロールを配置します。



・それぞれのコントロールの名称は、デフォルトのまま、「button1」「label1」です。

7. ボタンをダブルクリックして、ボタンクリックイベントを作成し、Form1.CSを編集しましょう。

 ・namespace参照用のusingに、「System.IO」と、「Nikon」を追加します。
  "using System.IO"は、撮影画像をファイルに保存するためメソッド呼び出し用に、
  "using Nikon"は、ニコンSDK(NkdPTP.dll)API呼び出し用です。

 ・Form1クラスで使用するプロパティとして、「NikonManager型のnknManager」と、「NikonDevice nknDevice」を定義しておきます。
 ※変数の名称は、私独自のルールで行っています。悪しからずご了承ください。

 ・Fom1クラスのコンストラクタで、nknManagerのインスタンスを
   new NikonManager("Type00**.md3");として作成します。 
 ※私の機種は、D5300なので、Type0011.md3でした。ここは、機種によって定義ファイルは異なります。

 ・さらに、このnknManagerのカメラデバイス接続/切断時に発生するイベントに、デリゲートメソッドを登録しておきます。
 ※NikonManagerについての、トーマスさんのWiki(英語)の説明をの貼り付けておきます。以下グーグル翻訳
  【NikonManagerは、システム上のカメラの到着と除去を追跡します。アプリケーションがNikonManager上のイベントをフックすることで、この情報を得ることができます。】
ということで、
nknManager.DeviceAdded += new DeviceAddedDelegate(manager_DeviceAdded);
nknManager.DeviceRemoved += new DeviceRemovedDelegate(manager_DeviceRemoved);
と、定義しました。

 ・デバイスの接続/切断時のイベントで実際に呼び出されるメソッドは次の通りです。
  ※以下、サンプルコードからのコピペです。

//デバイス接続時のイベントで呼び出されるメソッドです。
void manager_DeviceAdded(NikonManager sender, NikonDevice device) {
this.nknDevice = device;

//ラベルにデバイスネーム(カメラの種類:ここでは、”D5300”と表示される。)
label1.Text = device.Name;

// シャッターが押されて、撮影画像が準備出来たら呼び出されるメソッドを登録
device.ImageReady += new ImageReadyDelegate(device_ImageReady);
}

//デバイス切断時のイベントで呼び出されるメソッドです。
void manager_DeviceRemoved(NikonManager sender, NikonDevice device) {
this.nknDevice = null;//カメラデバイスを切断
}

//撮影画像がイメージバッファに準備出来た時に発火する(呼び出される)メソッドです。
void device_ImageReady(NikonDevice sender, NikonImage image) {
//ファイルは、実行ファイルと同じ場所に”Image1.jpg”として保存される。
using (FileStream stream = new FileStream("Image1.jpg", FileMode.Create, FileAccess.Write)) {
stream.Write(image.Buffer, 0, image.Buffer.Length);
}
}

シャッターを押して、写真を撮り、ファイルに保存するだけならこれだけでOKです。
当たり前のことですが、カメラの設定を"オート"にしておくと、露出、フォーカス、シャッタースピードすべて"自動"になります。
※ライブ画像表示時は、オートファーカスは効かないので要注意です。



2015年11月5日木曜日

その1:とりあえず、カメラのシャッターをパソコンで押してみよう。


◆プログラミングに必要なもの

・私の使用したプログラミング環境は、「visual studio 2015 community(VS2015)」です。

1.ニコンSDKをダウンロード

(ダウンロードサイトは、Googleで"ニコン sdk ダウンロード"で検索)

 アンケートに答えると、ダウンロードサイトの通知メールが届きます。

2.ニコンSDK C#ラッパーをWebサイトからダウンロードしてください。

 (ダウンロードサイトは、Googleで"Nikon SDK C# Wrapper"で検索)

※ダウンロードしたファイルには、サンプルソースがついていますが、説明は割愛します。
 (Webでは、多くの方が説明されていますので、そちらを参考にしてください。)




◆プログラミング開始

1. VS2015を起動し、新しいプロジェクトを作成する。

 ここでは、ウィンドウズフォームアプリケーション"WindowsFormsApplication1"を作りました。


2. ".Netフレームワーク"のバージョンを指定。

 C#ラッパーは、最新のフレームワークでは利用できないので、ツールバーの【プロジェク】トから、"WindowsFormsApplication1のプロパティ"を開き、左ペインの"アプリケーション"で、対象のフレームワークを".net framework 4 client profile"に設定します。


3. "プラットフォームターゲット"の指定

同様に、左ペインの”ビルド”から、プラットホームターゲットを、"Any CPU"から、"x86"に変更します。




4. "Nikon SDKラッパー"を参照に追加する

 ソリューションエクスプローラから、プロジェクトのツリーを展開し、参照を右クリックして、参照の追加をクリックして、"nikoncswrapper.dll"を参照に追加します。



※ニコンSDK"NkdPTP.dll"と機種別の設定ファイル"Type00**.md3"は、実行ディレクトリ("bin\x86\Debug"などに保存)

以上で、プログラム開発環境が整いました。

次回は、実際にカメラのシャッター制御を行います。

====コメント頂けたら、励みになります。===


「ブラウザで遠隔設置の一眼レフカメラをコントロールしよう」

と言うことで、ブログを開始しました。

◆使用するカメラは、ニコン一眼レフです。(※)

※今回利用するのは、D5300ですが、ニコンのSDKが利用できるカメラであれば何でもOKと思います。

※キャノンもSDKを一部公開しているようなのですが、日本向けには非公開のようです。

※SDKのAPI呼び出しに利用する言語は、C#で行いますす。このため、Thomas Dideriksenさんが公開されているNikon SDKのC#ラッパーを利用させて頂いています。トーマスさん有難く利用させていただきます。

◆Webサーバー側はIISで構築

・Webクライアントは、カメラを直接コントロールするPC(PCクライアント)と、そのPCへWebサーバーを通じて、シャッター押下指令を出すスマホなどのブラウザ側クライアントの2種類になります。

最新のブラウザが利用できれば何でもOKと思います。(スマホやiphoneでも大丈夫だと思います。)

・サーバーとクライアント(PC&スマホ)の交信は、IISのSignalRを使ったソケット通信で行います。
 (LInax系のサーバーだと、Node.Js+Socket.ioを利用することとになります。ここでは、SignalRを利用して構築します。)

・従って、サーバーはC#、クライアント(スマホ側)はHTML+JavaScript(JQuery)、PCクライアントはC#でコーティングします。

◆スマホ ⇔ サーバ ⇔ PC ⇔ カメラ

 (⇔は、すべて無線(WiFi)接続でも可能と思います。)

1.スマホから、画像公開用のWebサーバにブラウザを通じてSignalRのHubを呼び出すことでシャッター押下依頼を出す。 

2.サーバーは、スマホからの依頼を受けて、PCクライアント側のシャッター押下メソッドをHubを通じて呼び出す。

3.PCは、サーバに呼び出されたシャッター押下メソッドにより、カメラにシャッター押下指令を出す。

4.カメラはシャッターを押し、撮影画像をPCに転送する。

5.PC側のAPIは、画像がメモリバッファに準備ができれば、画像準備完了イベントを発火させ、FTPでサーバーへ画像を転送する。

6.FTP画像転送が終われば、PCはサーバーのHubメソッド呼び出しにて、ファイル名を通知する。

7.サーバーは、ブラウザ(スマホ側)に新しい画像のファイル名をHubを通じて通知する。

8.スマホ側は、ブラウザのImageタグで表示しているファイル名を通知されたものに変更し、ブラウザの画像をリロードすることで、撮影画像を表示する。

といった流れになります。

以下、サーバーの構築から、Webアプリやクライアントアプリ、ニコンSDKを使用するためのPC側のC#ソースなどを、順番に公開していきます。

非同期処理やソケット通信が感覚的に理解できるブログにしたいと思っています。

先は長いので、途中で息切れしないか心配ですが、頑張ってブログを更新していくつもりです。
お付き合いのほどよろしくおねがいします。


ご意見、ご質問何でも気軽に投稿ください。お待ちしています。