主にプログラミングに関して。Python, .NET Framework(C#), JavaScript, その他いくらか。
記事にあるサンプルやコードは要検証。使用に際しては責任を負いかねます

スポンサーサイト

                
tags:
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

C#: 時間のかかる処理を実行しつつもGUIでのインプットを受け付ける

                
 スクリーンキャプチャからGIFアニメを作るアプリをちょいと作っておきたかった。
 やり方としてスクショを一定時間ずつ撮ってGIFにして、それをGIFアニメの形式になるようにファイルに加えていって。そういうわけでGUIに中断ボタンをつけておき、ボタンクリックによってある変数がfalseになったらスクショ撮りをやめてGIFアニメを作るということがしたい。中断ボタンが押されるまでは(もちろんメモリ容量の限界があるのでフレーム数の限度も設けておくが)一定の時間間隔でスクショを撮り続ける。一定の時間間隔で撮り続けるということを実行するため、ループを回しその中での処理が特定の時間間隔になるように、一時停止を入れなければならない。
while (screenCap_continue)
{
Thread.Sleep(delayTime); //GetScreenが一定の時間間隔で行われるように調整
GetScreen();
}


 上記のような時間間隔の調整を別スレッドを立てたりせずに同期実行すると、Sleepによって処理が止まる。処理が止まるというのはGUIでのインプット待ちという処理までとまるということ。つまり変数screenCap_continueが書き換えられずに無限ループ。そこでGUIのインプット待機を続行するために非同期処理をこのあたりに適用した。Taskとasync、awaitを使うことで非同期処理の導入が楽になっている。

private void CaptureScreen()
{
while (screenCap_continue)
{
Thread.Sleep(delayTime); //GetScreenが一定の時間間隔で行われるように調整
GetScreen();
}
}

private async void MakeGifAnime()
{
await Task.Run(() =>
{
CaptureScreen();
}
}

private void CancelButtonPressed(object sender, EventArgs e)
{
screenCap_continue = false;
}
スポンサーサイト

Windows 10: ユニバーサルアプリを作ってみた その2

                
1507152230430.jpg

 Windows 10にはGroove Musicというオーディオファイル再生のためのアプリが入っているが、個人的には機能をそぎ落としたシンプルなものが使いたい。アルバムをクリックするたびにそのアルバムの詳細を表示する画面への遷移がいらない。遷移があると次のアルバムを選ぶために一覧へもどるという手間が増えて面倒。各曲の評価や時間の表示もいらない。聴きたい曲を流すだけなのでそんな情報は読まない。選んだアルバムのタイトル、アーティスト、収録曲がわかれば十分。というわけでユニバーサルアプリで自作してみる。機能をそぎ落としたものを作るので、標準搭載のアプリであるGroove Musicよりすごいものができるわけではない。簡単なものを作りつつ、ユニバーサルアプリ作成への理解を深めたかった。

 ユニバーサルアプリのパフォーマンスに関しては悪くないものになるようだ。.NET Nativeによってストアアプリのリリース設定版は中間言語ではなくネイティブコードにコンパイルされるとのこと。ユニバーサルアプリは公開時にMSのサーバにソリューションをアップロードして、ARM、x86、x64のそれぞれにコンパイルされて、ユーザがアプリをダウンロードするときに構成にあったものを落とさせるんだろう。

・オーディオファイル一覧とそのメタ情報の取得、各ファイルのアルバム単位への分割
 オーディオアプリということでまずはオーディオファイルとそのメタデータ収集。.NET Framework使用のアプリではDirectoryInfoなどからGetFilesで拡張子指定をかけてオーディオファイルを取ってこれた。
var files = new DirectoryInfo(uri)).GetFiles(".mp3", SearchOption.AllDirectories);
 これで集めたファイルをCOMのWMPLibにあるクラスに渡せばオーディオファイルのメタ情報を得られた。
var media = mediaInfo.wmpLib.newMedia(filePath);
var groupID = media.getItemInfo("WM/WMCollectionGroupID");
 このファイルアクセスやCOMの使用などのあたりは.NET Frameworkでやるのとユニバーサルアプリでは勝手が違う。そもそもユニバーサルアプリではファイルアクセスに制限がかかっているのもあるし。ただオーディオファイルのメタ情報を得たければ標準でFileStorageというオブジェクトから得る方法が準備されているところは助かった。
await KnownFolders.MusicLibrary.GetFoldersAsync(Windows.Storage.Search.CommonFolderQuery.GroupByAlbum);
上記のメソッドに渡しているクエリオプションによってどうフォルダを得るかを変えられる。GroupByAlbum以外にGroupuByArtist、GroupByAlbumArtistをはじめとしてジャンル別などわりといろいろ条件は準備されいる。アルバム一覧を表示するパネルにアーティストの名前順で表示したかったのでGroupByArtist、GroupByAlbumArtistなどを試してみたが、オーディオファイルがアルバム分けされずにアーティストの曲がごっちゃにまとまって返ってきた。なのでメタ情報取得後に改めてLINQなどでグルーピングしなおしたり。

・取得したオーディオファイルメタデータをデータベースへ
 オーディオファイルのメタデータを取得したら以降でその読み込みをとっとと行えるようにデータベースへつっこむ。簡単な構造でデータを保存するので柔軟性のあるドキュメント指向のデータベースが使いたかった。だがまだ対応したものはないらしいのでSQLiteを使用した。
http://www.codeproject.com/Articles/826602/Using-SQLite-as-local-database-with-Universal-Apps
 メタデータはアルバムごとにアルバムタイトル(string)、アーティスト名(string)、トラックタイトル(List)、ファイルパス(List)という具合にまとめたい。なるべく簡単にまとめたいので中間テーブルとか作りたくない(だからドキュメント指向データベースを使いたかった)。Listであるトラックタイトルとファイルパスがこのままじゃデータベースに保存できないけどどうするかなーと考えてみて、ListをJSONシリアライズすることで解決した。JSONのシリアライズ、デシリアライズもユニバーサルアプリでは新しいクラスが用意されていた。
https://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh770289.aspx
[Table("Album")]
class Album
{
[PrimaryKey]
public string AlbumID { get; set; }
public string Title { get; set; }
public string Artist { get; set; }
public int Length { get; set; }
public string _TrackPaths { get; private set; }
public string _Titles { get; private set; }
public DateTime Added { get; set; }

[Ignore]
public List<string> TrackPaths
{
get
{
var ja = JsonArray.Parse(_TrackPaths);
return (from a in ja.GetArray()
select a.GetString()).ToList();
}
set
{
var ja = new JsonArray();
foreach (var a in value)
{
ja.Add(JsonValue.CreateStringValue(a));
}
_TrackPaths = ja.Stringify();
}
}

[Ignore]
public List<string> Titles
{
get
{
var ja = JsonArray.Parse(_Titles);
return (from a in ja.GetArray()
select a.GetString()).ToList();
}
set
{
var ja = new JsonArray();
foreach (var a in value)
{
ja.Add(JsonValue.CreateStringValue(a));
}
_Titles = ja.Stringify();
}
}
}


 完成物イメージはこの記事のトップにスクショで置いてある。もしストアで公開するならもうちょい、コントロールがなにと連動してるかなどをわかりやすくせねばならない。だがとりあえず自分で使うぐらいには困らないかつ快適なものができた。
https://github.com/hMatoba/PlaneAudioU/tree/master/PlaneAudioU

Windows 10: シングルページWebアプリをユニバーサルアプリ化 - Project Westminsterを試す

                
 Windows10のリリースを前にしてさまざまな新機能が発表されてきた。そのなかでiOSアプリをWindowsにほぼそのまま移植することを可能にするProject Islandwood、同様にAndroidアプリのProject Astoriaは開発者間でも話題となった。これらはWindowsのモダーンなアプリが少なく、そっち方面のアプリの数ではiOSやAndroidに水をあけられていることの対策だろう。
 そんなWindowsデバイスのアプリの数の拡充策の一つに"Project Westminster"がある。これはブラウザで動作するシングルページのアプリケーションをユニバーサルアプリ化してしまおうというもの。ぼくはこれを初めて聞いたとき、ブラウザで動くものはブラウザで使えばいいじゃんと思った。だが世の中ではそう考えない人がけっこうスマフォユーザにいて需要があるらしい。どうやらアプリとしてパッケージ化されていないとダメで、ブラウザを使うという考えは基本的にないようだ。地図などはわからないでもないが、ショッピングでさえ個別のサイトがあろうとアプリ化されたものを使いたいらしい。・・・手間だ。そんなわけでWestminster
http://japan.zdnet.com/article/35067109/


 ぼくはいつだか外国のアマゾンでCDやDVDが日本より安く買えると聞いて、アマゾンのAPIを利用して日、米、英のお値段比較が送料込みで容易に計算できるサイトを作った。サイトと言っても操作はJavaScriptによるページ内容の変更で反映されるので、シングルページで使えるようになっている。
http://amazonstinger.appspot.com/
1507121941305.jpg
 Westminsterをこれで試してみる。チュートリアルは下記にある。
http://microsoftedge.github.io/WebAppsDocs/en-US/win10/CreateHWA.htm

 やることはチュートリアルをざっと読んでも簡単そうだが、VisualStudioがあるおかげでさらに難しくない。いつものアプリと同じく新しいプロジェクトとして指定のテンプレートを選び、自動で作成されているプロジェクト内のディレクトリやファイルの一部を消し、マニフェストファイルのXMLをちょっと書き足すだけだった。チュートリアルを読みながらやって5分以内で済む程度。
1507121818010.jpg

デバッグ実行してみる。
1507121818288.jpg
 サイトとして公開していたものが、一つのアプリとして動作した。すごく楽に。あとはストア登録ぐらいで公開にはもっていけるだろう。

 チュートリアルではここからユーザへの通知をトーストというコントロールを使って行うように書き換えている。

 結果としておそろしいほどに簡単にWebサイトからユニバーサルアプリを作ることができた。ただ元のサイトがウィンドウ幅などの面で他デバイス対応などを考えていないものだったので、そこらはbootstrapなどを使ってやっておかないとユニバーサルアプリとしていろんなデバイスで動かすのが不便になりそうだ。

.NET Framework: デスクトップビデオプレーヤーアプリを超フラットに

                
 Win10のユニバーサルアプリでひさびさにXAMLを触った反動か、ずっと前に作った.NETのデスクトップビデオプレーヤーをいじりたくなったのでやってみた。おもにやったのは各種GUIアニメーションの設定のしなおしや追加。

 ビデオプレーヤーなのでウィンドウいっぱいにビデオを表示したいと考えていたのでウィンドウの余計な装飾を取っ払って背景にビデオ映像をはめこみ。再生ボタンなどの各種コントロールを透過を使ってビデオ背景の上に配置。マウスがウィンドウから外れると各種コントロールがフェードアウトしてビデオ表示のみになる。コントロール表示状態のときは他のフラットデザインのアプリと同様にウィンドウに細いボーダーがついている。コントロール表示がフェードアウトするとこのボーダーもなくなって本当にビデオのみの表示になる。

1506282046424.jpg

1506282045341.jpg

Windows 10: ユニバーサルアプリを作ってみる

                
 Windows10のプレビューにVisualStudio2015のRC版を入れてある。これがどんな具合か調べたかったのでついでにユニバーサルアプリというのを作って試してみる。ユニバーサルアプリはおそらくWindows8でストアアプリと呼ばれていたもの。Windows10という名称でOSを多デバイス展開し、その上でならどのデバイスでも動けるようにしたのでユニバーサルという名称になった・・・という経緯のはず。
 ずっとWin7を使っていたのでストアアプリは作ったことがない。.NET FrameworkでならWPFアプリをいくつか。そのWPFアプリで作っていたビデオプレーヤーアプリをユニバーサルアプリとして再構築してみることにする。

 先に一つの結論を書いておく。ユニバーサルアプリは一つのアプリでさまざまな画面サイズに対応という特徴がある。VisualStudioにエミュレータがついてくるのでさまざまな画面サイズでデバッグを試せるというのが機能の一つだが、これは仮想マシン上でWin10を動かしている場合にはできないようだ。ぼくのWin10は仮想マシン上なのでこのエミュレータによるデバッグができなかった。



 ユニバーサルアプリを作るにあたってやることは、いつものVisualStudioアプリでやることと変わらない。新しいプロジェクトとしてテンプレートにユニバーサルアプリがあるのでそれを選んでプロジェクトを初期化。そしたら作成されたプロジェクト内にUIファイルやコードファイルができているのでそれを書き足してデバッグを行っていくのが基本。

 UIは基本的にXAMLで書く。StackPanelなどWPFと同じ要素が使えるけど、WrapPanelなどなかったりでWPFそのまんまでというわけにはいかなかったりする。

 WPFアプリを書いていたときとの違いはなんといっても非同期処理。msdnの記事を参考にぼくもWPFアプリのUIをいじるのに非同期処理を入れたことがあったが、UIスレッドとは別のスレッドを呼んで新しいUI要素で使うデータを加工して、変更を加えたい要素オブジェクトのInvokeメソッドを呼んでそこにデリゲートを渡して云々と慣れればなんてことはないが、かつては書き方としてはけっこう手間があった。ユニバーサルアプリではC#の進化によってasyncやawaitというキーワードを使って書くことができ、Invokeメソッドなどを呼ばなくてもUI変更もできていた。けっこう楽。このあたりWPFアプリ作成で使えるようになってるのか知らないので今後調べておきたい。とりあえずユニバーサルアプリではC#の進化によって非同期処理の導入がわりと簡単にできるようになっているということで。

 ファイルの入出力方法の変更も大きな違いだろう。WPFアプリではそれまでの基本的なWindowsアプリと同じで、権限さえひっかからなければ、とくにファイル入出力の宣言などを前もってする必要もなくやり放題?だった。なのでビデオプレーヤーを作ったときは、マイビデオディレクトリへのパスを割り出して、DirectoryInfoクラスを使ってそのパス下のファイル情報を収集してビデオファイルを集めてというふうにやった。ユニバーサルアプリではアクセスできるファイルが基本的に制限がかかっていて、使いたいファイルやディレクトリはあらかじめ宣言しておかなければならない、package.appxmanifestファイルで。ビデオファイルがほしい場合は
Capabilitiesノードに<uap:Capability Name="videosLibrary"/>を加える。<Capability Name="videosLibrary"/>のように書けるとどっかの公式ドキュメントページに例があっても、ページをよく見るとWin10インサイダープレビューでは前者のように書けとされている。これがわからずけっこう手間取った。
https://msdn.microsoft.com/en-us/library/windows/apps/dn934783.aspx


作ったのが下記のビデオプレーヤーアプリ。

Win10でデフォルト搭載のビデオアプリはライブラリを表示するたびにビデオ再生が停止する。ビデオを再生しっぱなしでライブラリを表示するために透過や要素のスライド、フェードを入れた。


 VisualStudio2015がどの程度できているかを試したくて、ユニバーサルアプリを作ることでそれをやってみた。途中でユニバーサルアプリの新しいUI要素がまだテンプレートに入っていないなどの情報をドキュメントで見ることはあったが、ユニバーサルアプリ自体はなんの問題もなく作れた。安定性においても、作ったものが小規模なものだったこともあるだろうが、動作に問題が出ることはなかった。
 ユニバーサルアプリ作成においてはWPFを作った経験があればけっこう使いまわせる知識はある。ただ微妙な差異が出てきてそれが面白かったり調べる手間でちょっと焦らされたり。WPFとユニバーサルアプリでは動作デバイスやファイル管理などを考慮すると適当な用途というのが違ってくると思うので適宜使い分けたい。たとえばPC環境でしか使わないという前提の業務アプリがWPFで作ってあるならそれはユニバーサルアプリに移植する有効性は薄いだろうし、タブレットでしか使わないアプリをこれから作るならユニバーサルアプリのほうがいいかもしれない。
プロフィール

h

Author:h

最新記事
リンク
作ったものなど
月別アーカイブ
カテゴリ
タグリスト

検索フォーム
Amazon
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。