ストアアプリを初めて作ります。
どういうアプリにするかイメージを膨らませ、要求文章を記述してみます。
(自分は思うのですが、この世界で最も難しい仕事は「企画」だと思います。)
画像ビューアです。
視線より次の画像に切り替わります。
声に反応できますが、声による入力は必須ではありません。
要望元は自分ですが、その自分にヒアリングを行っていきます。
さて、上記の要求についてお聞きします。
アプリを使用する場面を教えて下さい。
<問1>いつ・どこで・誰が・何のために・何を・どうする…場面ですか?
<答1>寝る前に、ベッドで、私が、電子書籍を読むため、電子書籍のページを、めくる場面です。
(画像ビューアの仕事かそれ?電子書籍のデータを解析すれば画像を表示できると考えるが、その辺確認入れてみるか)
<問2>ビューアの作成ではなく、電子書籍の閲覧アプリの拡張に聞こえます。
<答2>…そうかもね、その場合は電子書籍の閲覧アプリの拡張って可能なのですか?
…情報不足で答えられません。
要望元は画像ビューアがほしいと言っていましたが、要望の意図を確認した所、電子書籍の閲覧アプリの機能拡張として
視線からページをめくれさえすれば良いことがわかりました。
ストアアプリの拡張が可能かは、現段階では判断する材料が無いので調査が必要になります。
ちなみに電子書籍閲覧アプリは紀伊國屋の Kinoppy でした。
要望元は Windows 8.1 Pro が入ったタブレットで閲覧できて拡張できるならアプリはどれでも良い。
ファイルの解析などを行なうライブラリが提供されているならば一から作るでも良いという意向を示しました。
なるほど、電子書籍の閲覧アプリの作り方といった体で、既存アプリの拡張などが行えるか
市場にはどういった閲覧アプリが出回っているか調査することになりました。
まず電子書籍のデータ形式ですが、次のページで紹介されている通りいくつか存在します。
Kinopy で読んでた本のデータは .zbf 拡張子でしたので代表的なデータフォーマットの XMDF ですね。
こちらを読み込んで表示するアプリが多数存在することから、読み込みライブラリなどが公開されているのだと思います。
有料なのか無料なのか調べます。
えーと、残念ながら個人でのソフトウェア開発において、現在 XMDF の読み込みは行えないようです。(2014.03現在)
バイナリデータ作成元の会社の意見としては、ブックリーダーを個人で作らせたくないとのことです。(権利やお金の話?)
この世界の話はまったく知りませんでしたが、色々と調べてみて、とても気持ちが悪くなりました。
今、電子書籍業界は戦争しているようです。
書籍データ解析の選択肢が無いという調べがつきましたので Kinoppy の機能を拡張する方法で考えてみます。
ページをめくる方法はドキュメントに記載されており
マウスでドラッグしたり、タッチでスクロールしたり、キー操作では Space, BackSpace, アローキーなどでめくれました。
フォアグラウンドに Kinoppy を持ってくるとその他のストアアプリは中断状態に入りますので
マウスやキー入力操作に介入が出来ないように思えますが、どうなんでしょう?
前回学んだストアアプリの基礎にバックグラウンドタスクというものがあります。
フォアグラウンドからストアアプリが移動しても、プロセスが残り続けてダウンロードやメディアの再生を続けることができました。
こちら、キー入力イベントをバックグラウンドから投げ続けること
カメラの動画を入力として処理を継続できるか調べます。
(バックグラウンドタスクは制約が多いからダメっぽい気がするけど…確認します。)
…
もう少し電子辞書のフォーマットについて調べてみました。
ePUB は普通に zip 展開して、xhtml をウェブブラウザで読み込めば、内容を表示できるみたいですね。
先に楽天の kobo で買った ePUB ファイルを展開して中身を読み込んでみたいと思います。
zip を展開することは出来たのですが、コンテンツファイルが暗号化されている様子。
そのまま xhtml を読み込んで表示できるのか確認してみます。
だめでした。
青空文庫も Adobe DRM もコンテンツが暗号化されたままです。
ADE で同メールアドレスでオーソライズして開けると思っていた書籍までも、確認できませんでした。
いよいよお店が配っているリーダーのみでしか閲覧できないという制約がはっきりしてきました。
そう、私達はお金を払っても、ダウンロードしたコンテンツをどうこうして良い権利は受け取っておらず
作品をある制約の下で閲覧するだけの権利しか得ていなかったのです。(何を今更…)
はやくキー入力イベントを起こしてページがめくれるのか試してみます。
そういえば Visual Studio 2013 を使ってストアアプリ作ったことなかったですね。
知識はそれなりに用意出来ているので、軽く練習してみます。
とりあえず Visual Studio 2013 の起動。
あれ、いきなり Microsoft アカウントでサインインするように言われました。
とりあえずサインイン。
新しいプロジェクトより、[Windowsストア]→[グリッドアプリケーション]と選択します。
おや?DirectX アプリケーションというものがテンプレートにあります、なんでしょこれ?
気になったので DirectX アプリを先に試そうと選択すると Windows 8.1 開発者用ライセンスが求められました。
ライセンス取得はしましたが、登録後 1ヶ月で期限切れとなる模様、更新はメニューより
[ストア]→[開発者ライセンスの取得]で更新します。無料でいつでもいくつでもライセンス取得が可能だそうです。
(わざわざライセンス取得するのは不正なアプリ開発を防ぐための安全対策でしょうか?)
どきっとしたけど、なんだストアアプリをC++で用意していただけでした。
(C#から呼べるようになっていたのかと思っていたのに…ちなみに d3d11.lib をリンクしていました。)
この DirectX ストアアプリのビルド、実行を確認しました。
(頂点カラーを使ったボックスの回転アニメーションを確認しました。)
実行は作ったアプリのインストール+実行という扱いのようですが、普通にアプリを終了させる操作ではデバッグ実行が終了しません。
デスクトップに戻り、明示的にデバッグを中止することで、デバッグ実行が止まりました。(なるほど、なるほど)
気を取り直して、グリッドアプリケーションを触ります。
さてここで xaml の下のコードビハインドが .cpp だったのでなんか変だなと思ったら
メインとする言語を C++ として作業していたからでした。(アホか…)
C# の方で動作確認します。
さて、このグリッドアプリにて、キーイベントを取得して何かしらの反応をするように書き直します。
とりあえず、メインのグリッドビューの KeyDown イベントハンドラにて Space キーが押されたら
別ページヘナビゲートする機構を入れてみました。
実際にユーザーが Space キーを押下すると別ページヘナビゲートすることを確認しました。
これとは別にバックグラウンドタスクを実行するストアアプリを見てみましょう。
サンプルはこちら↓
TimeZoneBackGroundSample BackgroundTask
ちょっと雑談をします、Windows 8 マシンからマイネットワークを選択するとエクスプローラーがフリーズします。(何なの?)
上記のサンプルを真似して新しく Windows ランタイムコンポーネントをソリューションに追加しようとして
フォルダ選択ダイアログを出して、そこで右クリックしたら VisualStudio がハングしました。(ひどいバグだ)
おや?単にエクスプローラーにて右クリックするだけでもハングしますね。
うわわ!Windows 8 ごとハングしてしまいました。
再起動も出来ない!
Ctrl + Alt + Del でサインアウトできました。良かった。
月曜日になったので、また来週!
さて、バックグラウンドアプリのサンプルはしっかりトリガーに反応してブレークしますが、
まったく同じように作った自分のアプリでブレークポイントを同じ場所に設置しても
シンボルが読み込まれていないため?ブレークしませんでした。ちょっとー!?どうなっているの。
また、再起動してみます。
おや?今度はさっきまでブレークできたサンプルプロジェクトまで、ブレークポイントでブレークしなくなってしまいました。
(もういいです…)
調べて確信を得たのですが Windows Store アプリでは Windows.Form アセンブリの SendKeys.Send が使えません。
また、バックグラウンドタスクも裏でずっと走る処理というわけではありませんでした。
(トリガーを得て15分以上スリープした後1秒だけCPUを使えるとかその程度しかリソースをもらえません。)
中断状態に移行する処理にてずっとループして処理を実行するアプリも想像しましたが、これも現実的ではないですね。
外部アプリからストアアプリを操作するという方法は、簡単には見つからないことがはっきりしてきました。
さらに開発者のフォーラムで keybd_event をストアアプリで行いたいという書き込みがいくつもありましたが
公式の回答ではユーザー操作をコードから作成することは Windows Store アプリに限り出来ないようにしているとのことです。
セキュリティ上の問題らしいですね。
ということで、ストアアプリの Kinoppy を視線操作でめくるというバックグラウンドアプリは諦めましょう。
作る方法が無いことの調べがつきました(2014.03現在)ので、この世の誰にも実現は不可能です。
出鼻をくじられた感が強いですが、要望元には調査結果を突きつけて要望を取り下げてもらいました。
(自分なんですけどね…)
最初に誤って口にした画像ビューアを作る件で合意しました。(これも自分なんですけどね…)
ということで画像ビューアを用意し、これを視線で操作する方向に作業を持って行きたいと思います。
まずは視線をカメラから捉えるという処理が可能なのか調べてみましょう。
Google で簡単に調べた限りでは Gaze Tracking Library が良さそう。
さっそく使い方を確認してみます。
Web サイトはこちら→ Gazegroup.org
フォーラムにあるのはAPIドキュメントはなし、コード見ろとのことですね。
使ってみましたが思ったより精度が悪いです。
実際にどのように視線を検出しているか確認できたので面白かったですが
画像処理の部分がまだまだチューニングの余地を残す作りでした。
ちょっと自分でも作れそうなので作ってみます。
お、ではここから視線検出プログラムを設計していきましょう。
まずは要求分析ですね。
カメラのデバイスを検知して、ピクセル値へアクセス、読み書きできること
Windows Store, WPF からでも使えること
Sobelフィルタ、ハフ変換、領域分割などが高速に行えること
画像処理を拡張できるプラグイン機能を持つこと
…
とまぁ思いつきであれやりたい、これやりたいを列挙してそこからユースケースを書いて
ユースケースの記述に登場する名詞句、オブジェクトをドメインモデルに配置、整頓していきます。
EA から作ったページを html 出力します。
使い方はこちら→ドキュメントの生成とカスタマイズ
うーん、本当は html へのリンクを貼りたかったのですがIEからアクセス拒否されるので出力の一部の画像ファイルを表示します。
要約すると「画像処理したい→開発者は入力画像をフォルダにおいて、サンプルプラグインの一部の画像処理コードを作る」です。
precedes の矢印は先行を意味し、ユースケースが実行される前にそのユースケースが実行されることを示しています。
例えば入力画像を表示するためには、まず入力画像が読み込まれていないと始まらないといった具合です。
要求から派生した要求ということで汎化を使っていますが、表記としてはまったくのデタラメです。が、派生した要求なのでこのままとします。
確か教科書もユースケースは記述が大事で、線引きはどうでもよいとか何とか書いてあった気がします。(たぶん)
やりたいことには全て実現の矢印がユースケースから伸びているので、要求を漏れ無く実現できます。(たぶん)
ドメインモデルはこんな感じになりました。
最初の2時間の作業の結果がこれです。
では分析を行って、ここに書かれている間違いをどんどん修正していきましょう。
ロバストネス図をユースケースごとに書いていて気づいたことに、アクターがプラグイン開発者なので
バウンダリが常に VisualStudio という、これが参考にした教科書とまったく異なることに気付きました。
まぁ、ここからは本当にケースバイケースで、とにかくロバストネス分析の目的である属性やオブジェクトの抽出を行っていきます。
確かユースケースのリンクを貼り付けて、アクターからバウンダリに通信線を伸ばし、ユースケースの通りに
コントロール、エンティティを配置していきます。
ここでうまく配置作業がはかどらない場合はユースケースの記述がおかしいことに気づけるというものでした。
順番にユースケースに対応するロバストネス図を作っていきましょう。
ところで、任意のフォルダをドライブとして使うコマンド subst を使って
ユーザーフォルダの下に作った Workspaces を N: ドライブに割り当てました。
これにより C:\Users\simplestar\Source\Workspaces → N: に置き換わるので、ファイルパス管理が楽になります。
さて、ロバストネス図を書く前に一旦この .eap ファイルをサーバーに提出します。
これで一安心、いつでもこの状態に戻すことが出来ます。
編集を続けます。
プラグインの作成
確かにユースケースから簡単に描き起こせましたが、これであっているのかわかりません。
ただ、新しいオブジェクトは登場しませんのでこの図は無かったことにして良いと思います。
(これを描いてみて思ったことは、これは描くまでもなかったということですね。)
プラグインの編集
これも正しい図かどうかは置いておいて、プラグインを最初に作る際、まず骨組みとなるサンプルが必要であることに気付きます。
新しく登場したサンプルプラグインをユースケース、ドメインモデルに追加しました。
加えて、プラグインを識別するためにはユニーク値が必要なことに気付きます。
コントロールに「このユニークなプラグインIDを編集する」というものを追加し、
インタフェースクラス(→プラグイン基底クラス)にプラグインIDが必要であることがわかってきました。
これをドメインモデルに反映させます。
こんな感じでロバストネス図を描く、足りないものをユースケースとドメインモデルに追加する
という作業を繰り返していきます。
一通りロバストネス分析を行った後のドメインモデルを次に示します。
ドメインモデル
しまった、本当は属性だけ埋めるのですが、先走って操作を書いてしまいました。
ここまで記述して途中色々とシステムに対して要求が出てきました。
たとえば複数カメラの入力を同時に処理したい。
複数処理結果を同時に表示したい。
入力画像表示を再生、一時停止、停止、シークして巻き戻しなどして結果を確認したい。
などです。
これらの要求を取り入れて、ユースケースを追加、ドメインモデルの修正、ロバストネス分析を行います。
追加要求
これはプラグイン開発者ではなく、出来上がったプラグインをテストするテスターの操作となります。
かなり設計の教科書に似た状況なのでだいぶユースケースが書きやすくなりました。
ではロバストネス分析を行います。
途中 SharpDX を使って3Dモデルを出力結果に表示したいという要求が出たので
ちょっと最新版でサンプルが動くか調べてみました。
Unable to load DLL 'd3dcompiler_43.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
みたいなエラーダイアログとともにクラッシュしたので、解決を図るため次のランタイム更新を実行しました。
DirectX エンド ユーザー ランタイム Web インストーラ
結果は…大成功、上記の問題は解決しました。
ShaprDX サンプルがまず Windows 8.1 Pro 環境で動作することを確認。
問題は Desktop, Store どちらでも同じアセンブリを利用して同じ結果を得られるかどうかなのですが
この画像処理開発環境が完成したあとで確認してみましょう。
ロバストネス分析に戻ります。
追加要求のロバストネス分析後のドメインモデル
ひとまず分析はここまで、画像入力ストリームの作成をプラグイン化することで任意のデバイスを認識できるようになります。(たぶん)
つぎにやるのは「テクニカルアーキテクチャ」です。
いまのところ抽象的すぎて本当にプラグイン拡張できるのかとか、不明な点が多いです。
実装調査し、要素技術を確定させます。
ちょっと長くなりましたね。
引き続き設計を行いますが一旦話を切ります。
次回をお楽しみに。
2014/03/02 初記。
2014/03/23 更新。