国内ニュースの取得・表示と、人名から画像検索を行う2つのサンプルをつくる

2013年6月4日(火)
薬師寺 国安
<p>次に、ソリューションエクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbをダブルクリックしてリスト2のコードを記述します。</p> <h3>ロジックコードを記述する</h3> <h4>リスト2 (MainWindow.xaml.vb)</h4> <p>最新の HTTP アプリケーション用のプログラミングインターフェイスを提供するクラスの含まれる、System.Net.Http名前空間をインポートします。</p> <pre class="brush: plain; " type="syntaxhighlighter">Imports System.Net.Http </pre> <p>ファイル、フォルダおよびアプリケーションの設定を管理するクラスの含まれる、Windows.Storage名前空間をインポートします。</p> <pre class="brush: plain; " type="syntaxhighlighter">Imports Windows.Storage </pre> <p>シーケンシャルアクセスストリームおよびランダムアクセスストリームに対する読み取りと書き込みをサポートするクラスの含まれる、Windows.Storage.Streams名前空間をインポートします。</p> <pre class="brush: plain; " type="syntaxhighlighter">Imports Windows.Storage.Streams </pre> <p>コンテキストメニューおよびメッセージダイアログのサポートを提供するクラスの含まれる、Windows.UI.Popups名前空間をインポートします。</p> <pre class="brush: plain; " type="syntaxhighlighter">Imports Windows.UI.Popups Public NotInheritable Class MainPage Inherits Page </pre> <p>BitmapImage型の新しいリストであるImageListオブジェクトを作成します。</p> <pre class="brush: plain; " type="syntaxhighlighter"> Dim ImageList As New List(Of BitmapImage) </pre> <h4>[OK]ボタンがタップされた時の処理</h4> <p>WatermarkTextBoxが未入力の場合は処理を抜けます。入力された場合は以下の処理を実行します。</p> <p>変数myUrlに<br /> String.Format("http://api.photozou.jp/rest/search_public?type=photo&keyword={0}", Uri.EscapeDataString(WatermarkTextBox1.Text))<br /> と指定し、keywordに文字列をエスケープ表現に変換したWatermarkTextBox1の値を指定します。</p> <p>HttpClientの新しいインスタンスmyHttpClientオブジェクトを作成します。<br /> GetStringAsyncメソッドで、指定URIにGET要求を送信し、非同期操作で応答本体を文字列として取得し、変数resultに格納します。</p> <p>XElement.Parseメソッドで変数resultの値を文字列として読み込みます。</p> <p>Descendatsメソッドですべての<photo>要素のコレクションに対して、子要素<image_url>の値を変数resultに格納しながら反復処理を行います。</image_url></photo></p> <p>新しいImageのインスタンスmyImageオブジェクトを作成します。<br /> WidthとHeightにはDouble.NaNを指定します。これはAutoを指定したのと同じ意味になります。<br /> Sourceプロパティに<image_url>の値を持っている変数resultを絶対パスで指定します。<br /> ImageListオブジェクトにAddメソッドでmyImage.Sourceを追加しておきます。<br /> GridViewにAddメソッドでmyImageオブジェクトを追加します。画像の一覧が表示されます。</image_url></p> <p>非同期処理で行われるためメソッドの先頭にAsyncを追加します。</p> <pre class="brush: plain; " type="syntaxhighlighter"> Private Async Sub okButton_Click(sender As Object, e As RoutedEventArgs) Handles okButton.Click If WatermarkTextBox1.Text = String.Empty Then Exit Sub Else Image1.Source = Nothing ImageList.Clear() GridView1.Items.Clear() Dim myUrl = String.Format("http://api.photozou.jp/rest/search_public?type=photo&keyword={0}", Uri.EscapeDataString(WatermarkTextBox1.Text)) Dim myHttpClient As New HttpClient Dim result = Await myHttpClient.GetStringAsync(New Uri(myUrl, UriKind.Absolute)) Dim xmldoc As XElement = XElement.Parse(result) For Each result In From c In xmldoc.Descendants("photo") Select c.Element("image_url").Value Dim myImage As New Image myImage.Width = Double.NaN myImage.Height = Double.NaN myImage.Source = New BitmapImage(New Uri(result, UriKind.Absolute)) ImageList.Add(myImage.Source) GridView1.Items.Add(myImage) Next End If End Sub </pre> <h4>GridViewから画像が選択された時の処理</h4> <p>Image1のSourceプロパティに、myImage.Sourceを格納しているImageListから、GridViewから選択された画像のインデックスに対応する画像を指定します。これで、Image1に実寸の画像が表示されます。<br /> [Save]アイコンの使用を可能にします。</p> <pre class="brush: plain; " type="syntaxhighlighter"> Private Sub GridView1_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles GridView1.SelectionChanged Try Image1.Source = ImageList(GridView1.SelectedIndex) saveButton.IsEnabled = True Catch Exit Sub End Try End Sub </pre> <h4>[Save]アイコンがタップされた時の処理</h4> <p>ピクチャライブラリにアクセスします。<br /> CreateFolderAsyncメソッドでピクチャライブラリ内にWebSaveImageというサブフォルダを作成します。<br /> CreationCollisionOption.OpenIfExistsと指定すると、同名フォルダが存在する場合はフォルダ名を返し、ない場合は新規に作成します。</p> <p>Image1.SourceをDirectCastでBitmapImageにキャストして変数mySourceに格納します。<br /> 変数mySourceUriでBitmapImageを生成したグラフィックスソースファイルのURIを取得します。</p> <p>新しいHttpClientのインスタンスmyHttpClientオブジェクトを作成します。<br /> GetStreamAsyncメソッドで、指定したURIにGET要求を送信し、非同期操作で応答本体をストリームとして受け取り、変数myGetFileで参照します。<br /> WebSaveImageサブフォルダ内にCreateFileAsyncメソッドで現在の年月日時分秒.jpgファイルを作成します。<br /> OpenAsyncメソッドで現在の年月日時分秒.jpgファイルを「読み取り/書き込み」モードで開きます。<br /> CopyAndCloseAsyncメソッドで、ソースストリーム(myGetFile.AsInputStream)をコピー先ストリーム(myStream.GetOutputStreamAt(0))にコピーし、コピー操作が完了するまで待機します。<br /> AsInputStreamで、myGetFileをランダムの入力ストリームに変換します。<br /> GetOutputStreamAtはストリームの指定された場所の出力ストリームを返します。</p> <p>保存した旨のメッセージを表示し、[Save]ボタンの使用を不可とします。</p> <pre class="brush: plain; " type="syntaxhighlighter"> Private Async Sub saveButton_Click(sender As Object, e As RoutedEventArgs) Handles saveButton.Click Dim myFolder As StorageFolder = Windows.Storage.KnownFolders.PicturesLibrary Dim mySubFolder = Await myFolder.CreateFolderAsync("WebSaveImage", CreationCollisionOption.OpenIfExists) Dim mySource = DirectCast(Image1.Source, BitmapImage) Dim mySourceUri = mySource.UriSource Dim myHttpClient As New HttpClient Dim myGetFile As Stream = Await myHttpClient.GetStreamAsync(mySourceUri) Dim myStorageFile = Await mySubFolder.CreateFileAsync(DateTime.Now.ToString("yyyy年MM月dd日HH時mm分ss秒") & ".jpg", CreationCollisionOption.OpenIfExists) Using myStream = Await myStorageFile.OpenAsync(FileAccessMode.ReadWrite) Await RandomAccessStream.CopyAndCloseAsync(myGetFile.AsInputStream, myStream.GetOutputStreamAt(0)) End Using Dim myMessage As New MessageDialog("ピクチャライブラリのWebSaveImageフォルダに保存しました。") Await myMessage.ShowAsync saveButton.IsEnabled = False End Sub End Class </pre> <p>以上で今回の2つのサンプル解説は終了です。ありがとうございました。</p> <h3>筆者からのお知らせ</h3> <p>筆者はWindowsストアでアプリを公開しています。チャームの検索からWindowsストアを選択して、検索欄に、kuniyasuまたはYakushijiKuniyasuと入力すると、公開されているアプリの一覧が表示されます。上記はどちらも私のアカウントですので、興味のある方は是非ダウンロードして使ってみてください。</p>
  • RSSから国内ニュースを取得してタイルに表示するプログラム

薬師寺国安事務所

薬師寺国安事務所代表。Visual Basic プログラミングと、マイクロソフト系の技術をテーマとした、書籍や記事の執筆を行う。
1950年生まれ。事務系のサラリーマンだった40歳から趣味でプログラミングを始め、1996年より独学でActiveXに取り組む。1997年に薬師寺聖とコラボレーション・ユニット PROJECT KySS を結成。2003年よりフリーになり、PROJECT KySS の活動に本格的に参加、.NETやRIAに関する書籍や記事を多数執筆する傍ら、受託案件のプログラミングも手掛ける。Windows Phoneアプリ開発を経て、現在はWindows ストア アプリを多数公開中

Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。Microsoft MVP for Development Platforms - Windows Phone Development(Oct 2012-Sep 2013)。Microsoft MVP for Development Platforms - Client Development(Oct 2013-Sep 2014)。Microsoft MVP for Development Platforms-Windows Platform Development (Oct 2014-Sep 2015)。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています