PR

顔認識APIを使って写真に黒縁メガネをかける

2013年3月15日(金)
薬師寺 国安

ドキュメントライブラリへのアクセス許可

今回はドキュメントライブラリ内のImageFileList.xmlファイルにアクセスしますので、ドキュメントライブラリへのアクセス許可と、xmlファイルの登録が必要です。

※)ただし、Windows ストアに申請する場合、ドキュメントライブラリにアクセスしていると、パッケージファイルのアップロードではねられてしまいます。
ローカルで自分で使用する分には問題ないのですが、Windows ストアに申請する場合は、「画像ライブラリ」にアクセス許可を与えて中にフォルダを作成し、そのフォルダの中にImageFileList.xmlを配置して、読み込むようにしたほうがいいでしょう。

ソリューションエクスプローラー内のpackage.appxmanifestをダブルクリックして開きます。「機能」タブをクリックし、「機能:」にある「ドキュメントライブラリ」にチェックを付けます(図3)。

図3:「機能」タブ内の「ドキュメントライブラリ」にチェックを付ける(クリックで拡大)

次に「宣言」タブをクリックし、左に表示されている「使用可能な宣言:」から「ファイルの種類の関連付け」を追加します。右に表示されるプロパティ内で、「名前」にxml、「サポートされるファイルの種類」内の「ファイルの種類」に.xmlと指定します(図4)。

図4:「宣言」タブ内で「名前」と「ファイルの種類」を設定する(クリックで拡大)

※今回使用するImageFileList.xmlファイルは、“参考記事”で作成されたXMLファイルです。

次に、ソリューションエクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbをダブルクリックしてリスト2のコードを記述します。

ロジックコードを記述する

リスト2 (MainWindow.xaml.vb)

Option Strict On

クライアントとサーバーの両方で使用できる HTTP のコンポーネント(HTTP ヘッダー、およびメッセージなど)に関するクラスの含まれる、System.Net.Http名前空間をインポートします。

Imports System.Net.Http

シーケンシャルとランダムアクセスのストリームの読み書きをサポートするクラスの含まれる、Windows.Storage.Streams名前空間をインポートします。

Imports Windows.Storage.Streams

ネットワークで使用される多くのプロトコルに対し、インターフェイスを提供するクラスの含まれる、System.Net名前空間をインポートします。

Imports System.Net

ファイル、フォルダー、およびアプリケーションの設定を管理するクラスの含まれる、Windows.Storage名前空間をインポートします。

Imports Windows.Storage

XML ドキュメントオブジェクトモデル(DOM)をサポートするクラスの含まれる、Windows.Data.Xml.Dom名前空間をインポートします。

Imports Windows.Data.Xml.Dom

基本的な図形を定義するクラスの含まれる、Windows.UI.Xaml.Shapes名前空間をインポートします。

Imports Windows.UI.Xaml.Shapes

UIを提供するクラスの含まれる、Windows.UI名前空間を読み込みます。メガネの色を指定する場合等に必要です。

Imports Windows.UI

Public NotInheritable Class MainPage

  Inherits Page

メンバ定数変数に「取得した認証キー」を設定しておきます。

  ConstAppID As String = "取得した認証キー"

文字列型のリストである新しいmyImageListメンバ変数を宣言します。

  Dim myImageList As New List(Of String)

  Dim selectImageUri As String

Ellipseクラス型のメンバ変数myEllipseLeftとmyEllipseRightを宣言します。左目と右目のメガネになります。

  Dim myEllipseLeft As Ellipse
  Dim myEllipseRight As Ellipse

[サーバーから画像を取得]ボタンがクリックされた時の処理

ドキュメントライブラリにアクセスして、GetFileAsyncメソッドでImageFileList.xmlを取得します。

XMLドキュメントの読み込みと、解析の際に使用される設定の含まれる、XmlLoadSettingsクラスの新しいインスタンス、mySettingオブジェクトを作成します。DTDは含めないので、ProhibitDtdプロパティにFalseと指定します。外部エンティティ参照もしませんので、ResolveExternalsプロパティにFalseと指定します。

XmlDocumentクラスのLoadFromFileAsyncメソッドで、指定されたファイルからXMLドキュメントを非同期的に読み込みます。ドキュメントは指定された設定を使用して解析されます。

SelectNodesメソッドで要素のノードリストを取得し、ImageElement変数に格納します。

Countプロパティで要素のノードリストの個数を取得し、その個数分反復処理を行います。

繰り返し変数iに対応する要素の内容テキストを、ImageElement.ElementAt(i).InnerTextで取得し、変数myElementに格納します。リストのオブジェクトであるmyImageListにAddメソッドで要素の内容テキストを追加していきます。

参考記事”でサーバーに配置しておいたASP.NETファイルのImageDataフォルダー内にあるmyElementに格納されたファイル名を指定した文字列を作成し、myUrl変数に格納します。
CreateHttpメソッドで、指定したURI文字列用に新しいHttpWebRequestインスタンスを初期化した、myRequestオブジェクトを作成します。
MethodにGETを指定します。

GetResponseAsyncメソッドで、インターネット要求への応答を受け取ります。
GetResponseStreamでインターネットリソースから返されたデータストリームを取得し、変数myStreamで参照します。

メモリーに保存される入出力ストリームデータへのランダムアクセスを提供する、InMemoryRandomAccessStreamクラスの新しいインスタンス、myMemoryオブジェクトを作成します。
GetOutputStreamAtメソッドで、ストリームの指定された場所の出力ストリームを取得して、変数myOutputに格納します。CopyAsyncメソッドで、ソースストリームをコピー先のストリームにコピーします。この場合、Windowsランタイムの入力ストリームに変換された、myStream.AsInputStreamを、書きこまれる順次バイトストリームを表すmyOutputにコピーします。

新しいBitmapImageクラスのインスタンスbmpオブジェクトを作成します。
SetSourceメソッドに指定された場所の出力ストリームを取得している、myMemoryオブジェクトを指定します。

Imageの新しいインスタンスmyImageオブジェクトを作成し、WidthとHeightの値を指定します。Sourceメソッドにbmpオブジェクトを指定します。
GridViewにAddメソッドでmyImageオブジェクトを追加します。
サーバーからの画像が横1列に表示され、スクロールが可能になります。

非同期処理で行われるため、メソッドの先頭にAsyncを追加します。Asyncが追加されていると、その処理が非同期で行われることを意味します。

  Private Async Sub serverButton_Click(sender As Object, e As RoutedEventArgs) Handles serverButton.Click
 
    Dim myStorageFolder As StorageFolder = Windows.Storage.KnownFolders.DocumentsLibrary
    Dim myXmlFile As StorageFile = Await myStorageFolder.GetFileAsync("ImageFileList.xml")
    Dim mySetting As New XmlLoadSettings
    mySetting.ProhibitDtd = False
    mySetting.ResolveExternals = False
    Dim xmldoc = Await XmlDocument.LoadFromFileAsync(myXmlFile, mySetting)
    Dim ImageElement As XmlNodeList = xmldoc.SelectNodes("//画像名")
 
    For i As Integer = 0 To ImageElement.Count - 1
      Dim myElement = ImageElement.ElementAt(i).InnerText
      myImageList.Add(myElement)
      Dim myUrl = "ユーザーのサーバー名/ImageFileUpload/ImageData/" &myElement
      Dim myRequest = HttpWebRequest.CreateHttp(myUrl)
      myRequest.Method = "GET"
      Using myResponse = Await myRequest.GetResponseAsync
        Using myStream = myResponse.GetResponseStream
          Dim myMemory As New InMemoryRandomAccessStream
          Dim myOutputAs IOutputStream= myMemory.GetOutputStreamAt(0)
          Await RandomAccessStream.CopyAsync(myStream.AsInputStream, myOutput)
          Dim bmp As New BitmapImage
          bmp.SetSource(myMemory)
          Dim myImage As New Image
          myImage.Width = 320
          myImage.Height = 240
          myImage.Source = bmp
          GridView1.Items.Add(myImage)
        End Using
      End Using
    Next
  End Sub
Think IT会員限定特典
  • 顔認識APIを使って写真に黒縁メガネをかけるアプリサンプル

薬師寺国安事務所

薬師寺国安事務所代表。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のWebサイトにログインすることでさまざまな限定特典を入手できるようになります。

Think IT会員サービスの概要とメリットをチェック

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