からくりブログ

株式会社からくり社員のブログです

FlashAir用のWindowsアプリを組んでみよう!(JPEGビューア編)

大変ご無沙汰しております!

前回はFlashAirに格納されている画像のサムネイルを表示するプログラムをC#で組む方法を取り上げましたが、もう少しアプリとしての完成度を上げていきたいと思います。

今回はFlashAirの同人誌に掲載された記事を紹介します。記事中のWindows向けビューア・アプリも公開しますので、是非ダウンロードしてた試してみて下さい。

FlashAirの同人誌は秋葉原等で無料配布されています。


FlashAirって普段使いだとスマホやタブレットから専用アプリでアクセス、ホビーユースだと組込系のボード上でセンサーやカメラと組み合わせて使うケースが多いのかなって感じています。Windowsからアクセスする場合はSDカードスロットに挿してエクスプローラーでファイル操作したり、ウェブブラウザからアクセスするのが普通ですよね。入出力インターフェースが豊富で色んな使い方ができるFlashAirですが、私は「このデバイスはプログラムの学習にもってこいだ!」と感じました。そこで今回はFlashAir Developersさんで公開されているAPIを活用してWindows向けにJPEG画像ビューアを作成していきたいと思います。開発にはMicrosoft Visual StudioのC#言語でWindwosフォームアプリケーションを組む方法を採用したいと思います。今回作成するJPEG画像ビューア(FlashAirViewer)には大きく分けて以下の3つの機能を実装します。

  • FLashAir内の閲覧ディレクトリ(フォルダ)の移動
  • ディレクトリ内の画像データをサムネイル形式で一覧表示
  • 選択した画像本体をダウンロードして全画面表

 

至ってシンプルな機能ではありますが、通信・UIイベント制御・画像処理などプログラム的には様々な要素を含んでいますので、Windowsプログラミングの学習には最適だと思います。では、紙面の許す限り要点をかいつまんで説明していきたいと思います。

 

FlashAirのAPIを簡単に呼び出すには?


FlashAirには無線LANを使ったHTTP通信を用いてデータにアクセスする方法が、Application Programming Interface (API) として定義されています。今回は以下のAPIをC#から簡単に呼び出す方法を紹介します。

以下はファイルリストの取得APIを呼び出す時の記述例です。

string strResult =
DownloadString("http://flashair/command.cgi?op=101&DIR=/DCIM");

以下はファイル数の取得APIを呼び出す時の記述例です。

Stream stmResult =
OpenRead("http://flashair/thumbnail.cgi?/DCIM/100__TSB/DSC_100.JPG");

どうでしょう?WebClientクラスを使用すると非常に簡単に記述できますよね。

 

WebClientクラスのTIMEOUT時間を設定できるように拡張しよう!


便利なWebClientクラスですが、実は多少使いづらいところもあるのです。その一つがタイムアウトの時間が任意に設定できない事です。ここではWebClientクラスにタイムアウト時間を指定できるプロパティを追加する方法を紹介します。まずWebClientクラスを継承した派生クラスを作成し、タイムアウトプロパティを定義します。そしてGetWebRequest()メソッドをオーバーライドして指定したタイムアウト値を設定できるように書き換えます。以下はWebClientクラスを拡張した派生クラスの記述例です。

class WebClientEx : WebClient {
    private int timeout = 30000;
    
    public int TimeOut {
        get { return timeout; }
        set { timeout = value; }
    }

    protected override WebRequest GetWebRequest(Uri uri) {
        WebRequest wr = base.GetWebRequest(uri);
        wr.Timeout = timeout;
        return wr;
    }
}

時間のかかる処理は裏でコツコツやりましょう!


FlashAirのAPIを呼び出しが出来たところで、一つ問題が出てきました。FlashAirからサムネイルを取得して表示する際にFlashAirに保存されている画像ファイルの数が多いとその数に比例して処理に時間がかかってしまいます。問題と言うのはサムネイルを取得している間、何かしらの対策をしないとビューアアプリの操作ができなくなる事です。そこでここではサムネイルを取得のような時間のかかる処理を、メインの処理から切り離して、別のスレッドで非同期的に実行する方法を解説したいと思います。

Windowsのフォームアプリケーションで非同期処理を実装する場合、BackgroundWorkerコンポーネントを利用すると、簡単にバックグラウンドで処理を行うスレッドの記述ができます。BackgroundWorkerコンポーネントはVisualStadioのツールボックスから選択してFormにドラッグする事で追加できます。以下はビューアアプリ上でディレクトリ移動操作を行った際の処理をBackgroundWorkerコンポーネントを利用して記述した例です。

public partial class MainForm : Form {
    private void ChangeDirectory() { 
        if (backgroundWorker1.IsBusy == true) {
            // BackgroundWorkerで非同期処理の中断をする
            backgroundWorker1.CancelAsync();
            // バックグランド処理中間待つ
            while (backgroundWorker1.IsBusy == true) {
                System.Threading.Thread.Sleep(100);
                Application.DoEvents(); // ★★★
            }
        }
        // BackgroundWorkerで非同期処理を開始する
        backgroundWorker1.RunWorkerAsync();
    }
    private void backgroundWorker1_DoWork(object sender,
DoWorkEventArgs e) {
        BackgroundWorker worker = (BackgroundWorker)sender;
        foreach (サムネイルが個数分ループ) {
            if (worker.CancellationPending == false) {
                 // サムネイルを取得
Stream stmResult = OpenRead(strFileName);
                 // バックグラウンド処理の進捗をメインに通知する
                worker.ReportProgress(処理の進捗%);
            }
            else { // バックグラウンド処理がキャンセルされた時
                e.Cancel = true;
                return;
            }
        }
    }
}

WinMain関数のメッセージループって覚えてます?


BackgroundWorkerで非同期処理の中断をする記述の中(★★★の部分)にApplication.DoEvents()と言う見慣れないメソッドを呼び出しています。MSDNのドキュメントには「メッセージ キューに現在ある Windowsメッセージをすべて処理します。」と書いてあります。これをみて「ははーん!」と思ったあなたはMS-DOSプロンプトからwinコマンドをたたいてWindowsを起動させていたバブル世代や団塊Jr.世代のエンジニアの方ではないでしょうか?(笑)話がそれてしまいましたがBackgroundWorkerのスレッドは処理が完了(又は中断)した際にメインスレッドに処理の完了を通知します。そしてメインスレッドがこの通知を受け取るとIsBusyプロパティがfalseに遷移します。つまりDoEvents()を呼び出してメッセージ処理を行わないとバックグランド処理待ちのループから永遠に抜けられなくなるのです。怖いですね~。ちなみにメッセージループについて詳しく知りたい方はウィキペディア等で「イベントループ」を調べてみるとよいと思います。

 

実は…


さて、ここまで長々とお付き合い頂きありがとうございました。ここで重大な事実を告白いたします!実はWebClientクラスには.NET Framework 4.5 以降バージョンから非同期処理をサポートしています。と言うわけで今回BackgroundWorkerを利用して実装した非同期処理はWebClientクラスの非同期のメソッドを使用すればより簡潔にコードを記述する事ができると思われます。えっ?何でそれを先に言わないのかって?そ、それは…僕にもその色々と大人の事情がありまして…。と言うわけでこれに懲りずに是非また御付き合い下さいね!

 

ビューア・アプリのインストールと使い方


FlashAirViewerSetup.zipをダウンロードして解凍し、ソフトウェア使用許諾契約書に同意の上、setup.exeからアプリをセットアップしてください。

[wpdm_package id=’1716′]

アプリのセットアップが完了するとデスクトップにショートカットが作成されるので、そこから起動してください。

あらかじめ対象のFlashAirにWi‐Fi接続をしてください。

Connectボタンを押下するとFlashAirに接続を開始します。(APPNAMEは現在「flashair」に固定してあります)

接続出来たら閲覧対象のフォルダを選択してください。

サムネイル一覧が表示され、クリックすると画像を全画面表示できます。

全画面表示中に右クリックメニューで表示中の画像を保存できます。

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>