2013年12月30日月曜日

スタート画面の上品なタイル グラデーションを真似する試み

以前から気になっていた事なのですが... Windows 8 のスタート画面上のタイル、微妙なグラデーションと細い枠線が使われていて、例えば単にSolidColorBrushでGridViewのタイルをベタ描くよりもずっと上品でオサレな感じだなぁと感心していました。

このタイル一つ一つのグラデーションが上品で綺麗ですよね!ね?という話なんですが
同意してもらえるか一抹の不安を抱えつつ記事を書いています


年末年始で時間もあることですし、どういうロジックでこの上品な描画を行っているか確認してみようぜ!そして出来れば真似してみよう!という企画です。

アプリの場合、ソリューションの Package.appxmanifest でアプリケーション タイルの背景色を指定します。
しかし、この色がそのままFlatに描画されている訳ではないです。

下の画像がタイルサイズ「小」での実際の描画を拡大した様子なのですが、判ります?

・1px のボーダーが設定されている
・ボーダー・タイル内部 共、色は左辺から右辺へのGradient Brushになっている



例えば WiFiSD8 を例にとると、Appxmanifestで設定しているタイル色は#759AC4 なのですが、実際の描画はこの色で塗りつぶされている訳では無く、以下の様なGradient 付きで描画されています。


場所左辺右辺
サイズ大(310x310) タイル内部 759AC491B2D1
サイズ大(310x310) ボーダー 83A4CA9CBAD6
サイズワイド(310x150) タイル内部 759AC491B2D1
サイズワイド(310x150) ボーダー 83A4CA9CBAD6
サイズ中(150x150) タイル内部 759AC491B2D1
サイズ中(150x150) ボーダー 83A4CA9CBAD6
サイズ小(70x70) タイル内部 759AC490B2D1
サイズ小(70x70) ボーダー 83A4CA9CBAD6

つまり元の#759AC4 からタイル内右辺の#91B2D1(サイズ小の場合は#90B2D1), ボーダー(枠線)左辺の#83A4CA と右辺#9CBAD6, を何らかの方法で計算しているという事になります。

他アプリのタイルのデータも取ってみます。

場所左辺右辺
ストア タイル内部 1A961A1AAF1A
ストア ボーダー 83A4CA9CBAD6
IE タイル内部 2672EC2E8DEF
IE ボーダー 3C80EE4399F1
ミュージック タイル内部 D24726DC572E
ミュージック ボーダー D75A3CE06843
カメラ タイル内部 95008CAE00A7
カメラ ボーダー A01A98B61AB0

GreenとRed・Blueの増分差を見ると単にRGB値に定数掛け算している訳では無さそうなので、Windows的にお馴染みのHSL(HSVでは無く)に変換してみると

Excelとか持ち出して完全に見失っている様子


………うううーn……HSL に変換することでRGB 値から独立した変換係数的なのが出てくるかと思ったんですが、何か別の要素があるみたいです。又はHSL ではなくHSV でやっているのかもしれない。
とは言っても大体の傾向は判ります。左辺の値に「Saturation 1.01 / Lightness 1.10」 程度を掛けてあげると右辺の値になると。また、タイルのベースカラーからBorderへの変換は「 Saturation 0.9 / Lightness 1.10」あたりで。若干無理がありますが。

という事で、こういう掛け算をしてタイル・ボーダーのGradient Brushを作るとスタート画面っぽい上品なグラデーションが得られる、はず、です。やってみましょう。

(余談ですが、この記事30分くらいでちゃちゃっと書くつもりだったんですが、この時点でもう数時間経っている…RGB2HSL変換コードとか書いちゃうし何かもう見失っている 僕がマネージャーなら止めさせるレベル)

伝わらないかなぁ…


おおおお!!!!スタート画面のタイルっぽい!!かなり良い感じなのではないかと!僕は興奮しているのですが!
…でもなー…やっぱり、そもそものスタート画面のグラデーションの美しさが共有できていないとこの興奮も伝わらないのでは無いかという不安が消えません。

最後に

ストアアプリ、というかMetro Design Initiative では「Chrome排除!!」(※1)が鉄の掟、マントラな訳ですが…その割にはスタート画面で微妙にChromeってるのがずっと気になっていたのでした。人はマントラだけでは生きていけないのか。でもこれくらいなら上品で良いなと思います。

※1)Google Chrome の事では無いです。ウィンドウにドロップシャドウ落とす、XPのLunaみたいにつやつやさせる、左上からライトが当たっている前提でUI部品に変化つけたり、的な描画上の装飾(クロム)を排除しようぜ!という。Authentically Digital, 俺のカラダの筋肉はどれをとっても機械だぜ!(意訳)と並ぶ、Metro Designの柱です。



2013年12月29日日曜日

Segoe UI Symbol を手入力するには


Windows 8 でのUI 用フォントである所のSegoe UI Symbol、ストアアプリを作るには超便利で、futa8・WiFiSD8 共アイコンはほぼ全部これで間に合っています(futa8の塩辛アイコンは別)。

が、たまに…Segoe UI Symbol に何か書き足したい、少し弄りたい時があります。そういうときは Paint.netのようなペイントソフトに文字を入力し、編集して.PNGにしてアプリ内に持つのですが…その文字入力方法を毎回忘れては探しまた忘れ、を繰り返しているので…忘れた時用に記録しておきます。

2013年12月28日土曜日

WiFiSD8 Release 2

ストアアプリ版 FlashAir Client WiFiSD8 Release 2 を公開しました。Windows ストア からダウンロードできます。
既にインストール済みの場合、順次自動的に更新されます。

Click で ダウンロード
インストール・更新が成功した場合、設定→アクセス許可 に表示されるバージョン が「1.1.0.15」になります。

バージョン表示 設定チャーム→アクセス許可 で表示されます


変更点

一括ダウンロードの動作変更

動作がどう変わるのか

Release 1 では、WiFiSD8 が中断している間もダウンロードが継続していました。
Release 2 では、WiFiSD8 が中断している間、ダウンロードも中断します。

「WiFiSD8 の中断」とは?

Windows8 ではアプリが他のアプリの後ろに隠れると、数秒でアプリはOSに「中断」されます。
中断している間、アプリは一時停止している状態になります。ダウンロードも停止します。
アプリを前面に出して表示すると、アプリは再開し、ダウンロードも再開します。

「ダウンロードの中断」を避けるには?

一括ダウンロードの間、アプリを表示し続けることで中断を避けることができます。
一括ダウンロード中に他のアプリを使用したい場合、画面分割でWiFiSD8 を画面脇に表示する事で中断を避けることができます。

WiFiSD8 を画面左に寄せて表示している様子

Release 1 のほうが便利なのでは?何故変更を?

FlashAir Class 10 タイプ(W-02)用に「インターネット同時接続機能」対応ファームウェアが2013年11月にリリースされました。モバイルルータ等をお持ちの場合、外出中でも FlashAirに接続したままインターネット接続が可能となる画期的な機能です。

ところが、この新ファームウェアで追加された機能の一つ「リダイレクト」をOnにしていると、OSが「このシステムはインターネットから切断されている」と判断する場合が有ることが判りました(しない場合もあります)。
OSがこう判断した場合、Release 1 で使っていた「アプリ中断中もダウンロードを行う」機能 「Background Transfer」 は使えず、ダウンロードができなくなってしまうのです。
このため、WiFiSD8 Release 2 では 「Background Transfer」を使わず、一般的なAPI 「HttpClient」 で一括ダウンロードを行うよう変更しました。

WiFiSD8 側でリダイレクトモードのOn/Offを検知して情報を表示する、というデザインも検討したのですが、基本的に外出先で使う WiFiSD8 上で「リダイレクトをOffにして下さい」と表示したとしても、FlashAir のリダイレクトOn/Off 切り替えは FlashAir カードをSDカードスロットに挿入し、設定変更ツールを使う必要があります。大抵の場合、外出先でこの設定を変更することは出来ません。

また、新ファームウェアでは既定ではリダイレクトがOnとなっています。既定値の設定変更を前提としたアプリのデザインは無理があると判断し、今回の動作変更となりました。
ご理解頂ければと思います。


画像の全画面表示でのダウンロード・切り替えの改善、UIの変更


画像の全画面表示 モデルは友人のJ君です(掲載許可を貰いました)
全画面表示中の素早い画像切り替えでダウンロードが停止する場合がある不具合を修正しました。
また、ダウンロードキャンセルボタンを追加し、ボタン配置を見直しました。


Microsoft Application Insights サービス の追加

アプリの使用状況を取得するサービスです。アプリの起動回数、アプリ内の各ページの表示回数等が個人を特定出来ない形で送信されます。
既定ではオンになっています。
送信を停止するには、設定チャーム→WiFiSD8 設定→「Microsoft Application Insights の使用」をオフにして下さい。

Application Insights の設定

2013年12月25日水曜日

BackgroundTransfer を諦めた技術的背景 (その1)


今回、ストアアプリ WiFiSD8 で、所謂ダウンローダ…IriaやIrvineのような、複数アイテムを順次ダウンロードする機能…を実現しようとしました。

が、結果的には
「ストアアプリ特有のApplication Lifecycle Management 環境下ではBackground Transfer機能をもってしても中断・終了への対応は困難であり、ユーザーにアプリを前面に表示し続けてもらわない限り、複数アイテムの順次DLは難しい」
という事になってしまいました。

以下はこの結論に至るまでの逡巡の記録です。
こうすれば出来たのでは、というツッコミは大歓迎です。是非真似させてください。

StoreApp の Application LifeCycle Management について


ストアアプリの終了・中断は基本的にOSにより管理されます。これをApplication Lifecycle Management, ALM と呼びます。
ALM下では、アプリは3つの状態で管理されます。

動作(Running) アプリが前面に表示されている状態。ユーザーと対話し、普通に動作している状態です。

中断(Suspend) アプリが背面に移動すると、OSはアプリを中断します(アプリに拒否権は無い)。アプリが前面に表示されるとすぐに動作状態に復帰します。

終了(Terminated) システムのメモリがきつくなってくる等した場合、OSはアプリを終了します(アプリ側に拒否権は無い)。

アプリが背面に移動すると数秒で中断されます。また、アプリを複数同時起動していると、アプリはそこそこ頻繁に終了されます。

Desktop Appと大きく異なる点として、
  • Appを(いつでも)中断・終了する権利をOSが持っていること
  • Suspend状態があり、極めて頻繁にSuspend状態に入れられる事 またそこそこ頻繁に終了されること
 が挙げられます。

前者により、ストアアプリは何時OSに叩き殺されても構わないようにデータをマメに保存し、後者により、長い時間のかかるタスクは結構困る、という特徴(弱点)を持っています。
反面、Desktopのように長い時間使っているとプロセスがやたら増えてなんとなく不調、DiskやNetworkのような資源をアプリが使い放題、的な状況は起きにくい、という事でもあります。
 

BackgroundTransfer


さて、今回の…いわゆるダウンローダ、複数アイテムを一括で順次ダウンロードするアプリの場合、普通にHttp Clientを使うとアプリ中断でダウンロードも中断してしまうので困ったことになります。

このため、Win8/8.1では「BackgroundTransfer」という機能がOSに用意されています。
これは、OSに「このURLからファイルをDLして下さい」と頼むと、OSがダウンロードを行ってくれる、という機能です。ダウンロードの主体はOSであるため、アプリが中断している間も継続します。

…ですがこの機能、二つ問題があります。

  1. 複数アイテムのDLが使いにくい
  2. アプリが終了されるとバッチDLが終了してしまう

まず「1 複数アイテムのDLが使いにくい」 について説明します。

この機能、APIの設計やサンプルを見るに、大きな1つのファイルをDLするためにデザインされている機能で、複数アイテムを一括でDLすることは(あまり)考えられていないのかな?という気がします(APIが用意されてはいるが、事実上動作として意味が無い)。

BackgroundTransfer が想定しているフローは、

  1. OSにDLアイテムを1個登録
  2. OSがDLを終え、アプリに通知
  3. アプリは次のDLアイテムをOSに登録
であるようです。
ですがこれはバッチダウンローダとしてはNGです。アプリが中断している間に2. に至った場合、次のアイテムを登録する事ができず、バッチプロセスが中断してしまいます。

このため、WiFiSD8 Release 1 では、(多分)想定外の使い方をしていました。

  1. OSにDLアイテムを一気に全部登録
  2. OSはひたすらDL

(想定外と言うのは…本来アイテム登録は await RunAsyncで行い、DLが終了したらawaitから返ってくる、のですが…Release1ではこのCallをasync voidのMethodに押し込み、Callしたら後は知らんぷりでぶん投げるという。酷い。でも、これでもDLの進捗・終了はCallbackで取得可能です。)

この場合、アプリが中断されてもOSは次から次へとDLを繰り返します。
ですがSideEffectがありまして…1の全部登録に結構時間が掛かります。100アイテム登録に一分くらい掛かってしまう。AsyncAwaitのお蔭でアプリのUIが固まる事こそ無いものの、1分はかなりの数のDLが済ませられる時間であり、どうしたものか…という所でした。
 
ですが(この文章ですがだらけですが!)、この想定外の使用をもってしても、
「2 アプリが終了されるとバッチDLが終了してしまう」
これは克服できません。
 正確には、1アイテムのDLはアプリが終了しても継続します。
が、次のアイテムのDLが始まらず、バッチ処理が止まってしまうのです。

ここまでの話をまとめると、

・BackgroundTransfer を使う事で、(開始に時間は掛かるが)アプリ中断でも終了しない一括ダウンロードを実現可能。ただしアプリ終了に対しては無力。

となります。WiFiSD8 Release 1はこの方法を取っていました。
アプリ中断に対しては大変有効な方法なのですが、困るのは…アプリが中断されるか終了されるか、ユーザーから見ると全く予測ができない所です(開発者でも無理ですが)。
そして、アプリ終了をユーザーが防ぐ唯一の方法は、

「アプリを背面に持っていかず、前面に表示し続ける」

これだけです。
・・・あれ?と。ここまで読んで頂いた忍耐深くまた賢明な貴方様なら、議論が循環している事にお気付きかと思います。

「前面に表示し続けるのがアリなのなら、そもそもBackgroundTransfer 使わなくても良くね?HttpClient 使っても同じじゃん!!」

という。
そういう矛盾をWiFiSD8 Release 1 は孕んでいたのでした。
矛盾はありますが、それでも機能を実装することで中断に対応する事が出来、損はしていないはずでした。

ですが、この状況は全く別の要因で大きく変わり、結果的にはBackgroundTransferを使わないRelease 2を作る事になるのでした。
長すぎなので章を分けます。
待て次号。

※ 今回、Background Taskについては15分にCPUTime 2秒ではDLには使えないだろうということで上の考察には入れていません。




2013年12月14日土曜日

ListViewにItemを幅一杯にみつしり表示させるには

WiFiSD8 の作業中に気付いた話。
Win8.1でアプリの幅が可変になりました。
それで、狭幅用の1次元なListViewを持とう、とXAMLを弄っていて、あれ?と。



左中のアプリがそれです。幅一杯にアイテムを広げて表示したかったのですが、モノによっては短く表示されてしまう。???

なんでかなーとパソコンに向かって呟いていたら(twitter)、超イカすTwitterClient App "Mevy"を作っておられる雪猫氏に「ListView/ListViewItemのHorizontalContentAlignmentをStretchにすればいいのでは?」という情報を頂き、さっそく試してみたのだけれども…結果は同じでした。
無念。

んんんnーー何故ーと上の画面を見ていて気づくのは、日付の下の数字が「1」のアイテムだけ幅の変化が出来てないと。

このDataTemplate、中にはFlipViewが入っていまして、


 こんなのです。
「1」というのは、アイテムが内包する写真の数が1、つまりFlipViewに載っているアイテムの数が1、という意味です。

 今回の様に可変長域にみつしり詰めたいとき、「これだけ幅が欲しい」と親のコンテナに要求を出せるElementが必要です。
例えば上のTemplateで、もし一番幅が大きいのが幅300のStackPanelだったとしたら、このTemplateがはまるListViewの幅がなんぼ大きくても別に広がったりはしないと。

上の場合、そういう要求を出す原動力になっているのはFlipViewの中のImage"FlipViewItemOriginalImage"だけです。ここでStretchが「UniformToFill」になっているが故に、親に「くれるだけ幅をくれ!幅を!」という要求が通り、みつしり表示されると。

で、今回の場合・・・どうも、FlipViewの中のアイテムが1個だけの場合、意図したようなRequestが飛んでいかないがために、一番上の画像のような事になっているのかな、と。
何故?というのは今回わからなかったです。すみません。

回避策として・・・カッコ悪いのですが、FlipViewの代わりに親に幅を寄越せとRequestできるアイテムを一個置くことにしました。上のDataTemplateでコメントアウトされているRectangleです。Color#00000000のため見えないですが、Stretch=UniformToFillな為親に「幅をくれるだけ寄越せ!!」と要求します。

このWorkaroundで、意図した動作をさせることが出来ました。


2013年12月12日木曜日

WiFiSD8 動作の様子(動画)

WiFiSD8 動作の様子を動画で撮影してみました。
FlashAir Card が動作に必須なアプリのため中々動作を伝えづらい、というのが理由です。



撮影方法は、

  1. Giffing Tool でスクリーンキャプチャ撮影・Gifアニメ化 を行う 50-60MB程度のアニメGIFファイルが出来上がる
  2. gfycat.com にアップロード gfycat はGIFアニメをHTML5 VideoにEncodeして公開してくれるWebサービス
  3. アップロードすると外部リンク用のiframe linkが出てくるので、それをBloggerのHTML編集モードで貼り付ける
GIFアニメの割には結構良い感じに撮れていて、ストアアプリの紹介・チュートリアル等に使えるなと思うのですが、どうでしょうか。


Giffing Tool (シェアウェア、支払料金は任意)
http://www.giffingtool.com/

gfycat
http://gfycat.com/

2013年12月8日日曜日

WiFiSD8: 一括転送が始まらない不具合について

WiFiSD8には複数画像を一括で転送する機能があるのですが、場合によっては転送が始まらない不具合が有ることが判りました。

確認できた再現条件

「FlashAir Class10 モデルで、リダイレクトモードを「On」にしている場合」

リダイレクトモードがOnの場合、FlashAir にWiFi接続すると自動的にFlashAirのWebページが開きます。
又は、FlashAir Tool で確認できます。

なお、Class10 モデルでFW2.00.02(インターネット同時接続をサポートするVersion)にアップデートしている場合、既定値は「リダイレクトモードOn」です。

FlashAir Tool 「ネットワーク設定」画面


確認できた現象


WiFiSD8の一括ダウンロードにファイルを追加し、「Start」ボタンを押すと、ダウンロードが始まるはずの最初のアイテムが「中断」表示のまま状態が進行しない。

問題が発生する場合、囲み部分が「中断」のままになります



回避方法

FlashAirの「リダイレクトモード」 をOff にして使用する。

Offにした場合、接続時にWebブラウザが自動的に開かなくなります。
また、この場合でもインターネット同時接続機能はお使い頂けます。

または、

WiFiSD8 の一括ダウンロード機能を使わない。
画像表示によるファイル保存は正常にお使い頂けます。

原因

WiFiSD8 は、一括ダウンロード時に WinRT API 「BackgroundTransfer」を使用しています。このAPI を使うとダウンロードはOSにより行われ、アプリケーション(WiFiSD8)がOSによりApp Suspendされている間も、ダウンロードが継続します。
ですが、このダウンロードは「インターネットからシステムが切断された」とOSが判断すると転送を中断します。
リダイレクトモードOn はOSに「インターネットからシステムが切断された」と判断され、以上のような現象になっているようです。
(OSが何を持って「切断された」と判断しているのか不明のため、最後の歯切れが悪く申し訳無いですが…)

なお、画像の画面表示でダウンロードを行う場合、BackgroundTransfer では無く、WiFiSD8 が自分でHttpClient API を使って行っているため、この問題は発生しません。

その他

手持ちのカードで確認した限りでは、FlashAir Class6 ではこの問題は発生しないようです(そもそもClass6にはリダイレクトモードが無いためと思われます)。

2013年12月7日土曜日

WiFiSD8 をリリースしました

WiFiSD8 TopPage
 
 
WiFiSD8 は、WiFi機能付きSDカード内の写真を閲覧・保存するための Windows 8.1 / Windows 8.1 RT 向け Store Applicationです。
東芝 FlashAir に対応しています。

Windows Store からインストールできます。
http://apps.microsoft.com/windows/ja-jp/app/wifisd8/1f490d0d-4c05-4417-ac24-f51c24e29c2b


WiFiSD8 を使う利点

 
 今回対応したFlashAir はWeb ブラウザ UIを内蔵しており、アプリ無しでも写真を閲覧することができるのですが、
 WiFiSD8 は専用のWindows StoreAppとして、

  • StoreApp の作法に沿った、タッチ・マウス共に使いやすいUI  … Gridで表示する大きなサムネイル、フルスクリーン表示で左右にスワイプして画像切り替え等
  • 保存の簡略化  元画像を表示後自動でユーザーの指定したフォルダに日付毎に保存
  • 複数画像を一括で転送・保存
  • リサイズ・共有をDesktopに降りずにアプリ上で実行
等、Webブラウザ では得られない機能・使い勝手を提供できていると考えています。

 


…以下、「WiFi機能付きSDカードって何?」という背景話を簡単にまとめました。

......

 

WiFi機能付きSDカード とは?


WiFi アクセスポイント と、Webサーバを内蔵したSDカードです。
カメラに挿して使うと、カメラからは一般のSDカード同様に写真を記録できます。
同時にアクセスポイントとWebサーバが動作しており、タブレット・PC・スマートフォン等よりアクセスポイントにWiFiで接続すると、Webサーバが写真を見せてくれる、という動作をします。

(画像はFlashAir Developersより拝借)

基本的に、どんなカメラでもSDカードさえ使えればWiFi対応カメラに化けさせることができるのがポイントです。

今回対応した東芝 FlashAir は、
  • HTML Interface
  • CGI Interface
の二通りのInterfaceがあり、両者とも仕様が公開されています。

FlashAir Developers
https://www.flashair-developers.com/ja/

WiFiSD8 は後者を使ってファイルリストを取得し、画像を表示します。
 
※カメラによってはノイズの影響で通信が不安定になることもあります。対応カメラかどうかを確認するのが大事です。

FlashAir™ Class6 動作確認機器一覧
http://www.toshiba.co.jp/p-media/compati/flashair_c6_list.htm

FlashAir™ W-02 Class10 動作確認機器一覧
http://www.toshiba.co.jp/p-media/compati/flashair_list.htm

 

現状


この種のデバイスが登場したきっかけの一つは、おそらく、iOS系デバイスやスマートフォン・タブレットにカメラを接続するのが中々めんどくさい、事があります。SDカードを挿すには変換アダプタが要りますし、USBも直接は刺さりません。
今までPCでやっていた作業の多くがスマートフォン・タブレットに移行している中、カメラが置いて行かれている所がありました。

また、上とも重複する話ではあるのですが、「写真の使われ方」が変化しているという部分もあります。
出先で写真を撮ったらすぐツイート・共有する、という近年の「写真の使われ方」は専ら携帯電話・スマートフォン内蔵カメラでのユーザー体験であり、一々PCに繋げて転送して…という「単体カメラ」はこのシナリオから置いて行かれている感がありました。

他方、携帯のカメラでなく、良いレンズを持った「単体カメラ」で撮った写真を出先からツイート・共有したい、というニーズもあります。

それらを橋渡しするデバイスとして、WiFi機能内蔵 SDカードが使われるようになってきている、又WiFi機能内蔵カメラが増えている、というのが現状であろうと考えています。