酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

WindowsストアアプリでHttpWebRequestを使ってインターネットからダウンロードした画像を表示させる

この記事は、2012/7/16現在にリリースされている最新の「Windows 8 Release Preview(Build 8400)」、「Visual Studio 2012 RC」を利用しております。「Windows 8 Release Preview」は開発中のものであることにご留意ください。

インターネット上の画像をダウンロードし、Imageコントロールへ表示させる場合、Windows Phoneアプリではすごくシンプルで、HttpWebRequestで得られたレスポンスストリームをBitmapImageインスタンスに食わせ、ImageコントロールのSourceプロパティへ設定するだけでした。

この記事では、Twitterで僕が使用しているアイコンをダウンロードして、Imageコントロールへ表示する方法を紹介します。

Metro スタイル アプリでは、BitmapImageインスタンスへはStream型をそのまま読み込ませることができないため、画像をダウンロードし、そのストリームをInMemoryRandomAccessStreamへソースストリームをコピーする必要があります。

  • HttpWebRequest/HttpWebResponseで画像をダウンロード
  • ストリームをInMemoryRandomAccessStreamへコピーする (WP7と比べての追加)
  • BitmapImageへInMemoryRandomAccessStreamを設定
  • ImageコントロールへBitmapImageを設定

よって手順としては1ステップ多くなってしまうのですが、以下のサンプルコードの通りです。

private async void btnRefresh_Click(object sender, RoutedEventArgs e)
{
    var url = "<ダウンロードしたいファイルのURL>";
    var req = HttpWebRequest.CreateHttp(url);
    req.Method = "GET";
    using (var res = await req.GetResponseAsync())
    using (var strm = res.GetResponseStream())
    {
        // BitmapImageインスタンスへはStream型をそのまま読み込ませることができないため、
        // InMemoryRandomAccessStreamへソースストリームをコピーする
        InMemoryRandomAccessStream ims = new InMemoryRandomAccessStream();
        var output = ims.GetOutputStreamAt(0);
        await RandomAccessStream.CopyAsync(strm.AsInputStream(), output);

        // BitmapImageへソースを設定し、Imageコントロールで表示させる
        var bitmap = new BitmapImage();
        bitmap.SetSource(ims);
        image.Source = bitmap;
    }
}

XAML

今回の例だとXAMLを掲載してしまうと大きくなりすぎてしまうので、省略してしまいたいところなのですが、念のためXAMLをコピペしておきます。

<Page
    x:Class="MetroDokei.MainPage"
    IsTabStop="false"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MetroDokei"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Page.BottomAppBar>
        <AppBar x:Name="bottomAppBar" Padding="10,0,10,0">
            <Grid>
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Left">
                    <Button x:Name="btnRefresh" Style="{StaticResource RefreshAppBarButtonStyle}" Click="btnRefresh_Click"/>
                </StackPanel>
                <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
                </StackPanel>
            </Grid>
        </AppBar>
    </Page.BottomAppBar>
    
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Image x:Name="image" Source="Assets/Logo.png"/>
    </Grid>
</Page>