酢ろぐ!

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

.NET Framework APIの型をWindows Runtime APIの型を変換する(応用編)

本日は、Windowsストアアプリ Advent Calendarの第14日目です。

Windowsストアアプリでは、.NET Framework APIとWinRT APIの両方を混在させて扱うことができることは、「.NET Framework APIの型をWindows Runtime APIの型を変換する」にてご紹介させていただきました。

今回は、タイトルとは異なった内容ですが応用編というか、応用例について紹介したいと思います。

ファイル操作関係

「型を変換する」という書き方は変ですけれど、ついでにストリームやバッファとよく絡ませるファイル操作関係の処理についても、これまで書いてきたフォーマットに合わせて紹介します。

Windowsストアアプリでは、FileIOクラスを使えば大抵のことができそうです。WindowsストアアプリとWindows Phoneアプリで同じソースコードを共用したい場合にはFileIOクラスが使えませんので、FileIOクラスを使わない書き方をしなければいけませんのでご注意ください。

StorageFile to IBuffer

Windows.Storage.StorageFileからWindows.Storage.Streams.IBufferの変換です。

いわゆるファイルの読み込みですね。FileIOクラスのReadBufferAsyncメソッドを使ってIBufferへ読み出すことができます。

// using Windows.Storage;

StorageFile file = GetFile(xxxx);
var buffer = await FileIO.ReadBufferAsync(file);

IBuffer to StorageFile

Windows.Storage.Streams.IBufferからWindows.Storage.StorageFileの変換です。

いわゆるファイルの書き出し(保存)ですね。StorageFileオブジェクトのOpenAsyncメソッドを使って(IRandomAccessStream型の)ストリームを開き、WriteAsyncメソッドを使ってIBufferの内容を書き出します。

// using Windows.Storage;

StorageFile file = GetFile(xxxx);
using (var outputStrm = await file.OpenAsync(FileAccessMode.ReadWrite))
{
    await outputStrm.WriteAsync(buffer);
}

もしくはFileIOクラスのWriteBufferAsyncメソッドを使う方法があります。こっちの方が簡単かもしれませんね。

// using Windows.Storage;

StorageFile file = GetFile(xxxx);
await FileIO.WriteBufferAsync(file, buffer);

画像ファイル操作関係

こちらも「型を変換する」という書き方は変ですけれど、ついでにストリームやバッファとよく絡ませる画像ファイル操作関係の処理についても、これまで書いてきたフォーマットに合わせて紹介します。

IRandomAccessStream to BitmapImage

Windows.Storage.Streams.IRandomAccessStreamからWindows.UI.Xaml.Media.Imaging.BitmapImageの変換です。

// using Windows.Storage.Streams;
// using Windows.UI.Xaml.Media.Imaging;

IRandomAccessStream stream = GetXXXXX();

BitmapImage image = new BitmapImage();
image.SetSource(stream);

byte[] to WriteableBitmap

byte型配列からWindows.UI.Xaml.Media.Imaging.WriteableBitmapの変換です。

byte型配列にはピクセルデータだけが入っていることを想定していますので、あらかじめ画像の幅と高さについては知っておく必要があります。

// using Windows.Storage.Streams;
// using Windows.UI.Xaml.Media.Imaging;
// using System.Runtime.InteropServices.WindowsRuntime;

var width = 640;
var height = 480;

WriteableBitmap bitmap = new WriteableBitmap(width, height);
using (var pixelStream = bitmap.PixelBuffer.AsStream())
{
    pixelStream.Seek(0, SeekOrigin.Begin);
    pixelStream.Write(array, 0, array.Length);
}

IRandomAccessStream to WriteableBitmap

Windows.Storage.Streams.IRandomAccessStreamからWindows.UI.Xaml.Media.Imaging.WriteableBitmapの変換です。

BitmapDecoderを使ってデコードし、含まれる画像のサイズとピクセルデータを読み込みます。ピクセルデータはbyte型配列ですので、前述のbyte[] to WriteableBitmapの方法を使ってWriteableBitmapオブジェクトを作ります。

// using Windows.Storage.Streams;
// using Windows.UI.Xaml.Media.Imaging;
// using Windows.Graphics.Imaging;
// using System.Runtime.InteropServices.WindowsRuntime;

// ストリームからデコードして、画像サイズとピクセルデータを読み込む
var decoder = await BitmapDecoder.CreateAsync(stream);
var transform = new BitmapTransform();
var pixelData = await decoder.GetPixelDataAsync(
    decoder.BitmapPixelFormat, decoder.BitmapAlphaMode,
    transform, ExifOrientationMode.RespectExifOrientation,
    ColorManagementMode.ColorManageToSRgb);
var pixels = pixelData.DetachPixelData();

// デコードしたピクセルデータをWriteableBitmapへ書き込む
WriteableBitmap bitmap = new WriteableBitmap(
    (int)decoder.OrientedPixelWidth,
    (int)decoder.OrientedPixelHeight);
using (var pixelStream = bitmap.PixelBuffer.AsStream())
{
    pixelStream.Seek(0, SeekOrigin.Begin);
    pixelStream.Write(pixels, 0, array.Length);
}

あとがき

しかし、この記事誰かの役に立つのだろうか……。

Windowsストアアプリを開発している人はみんな知ってそうな気もする。この辺りのことは依然書いた書籍でも取り上げています。もしWindowsストアアプリの開発で困ることがあれば、「Windows8ストアアプリ開発入門」と「Windowsストアアプリ開発のレシピ110」をお読みください。

今までWindowsストアアプリの開発をしたことがない方であれば前者の「Windows8ストアアプリ開発入門」をお読みください。

Windows8ストア アプリ開発入門

Windows8ストア アプリ開発入門

もうすでにWindowsストアアプリの開発をしていて、大まかには知っているので逆引き的に調べたいという方であれば後者の「Windowsストアアプリ開発のレシピ110」をお読みください。

Windowsストアアプリ開発のレシピ110

Windowsストアアプリ開発のレシピ110

それでは、楽しいWindowsストアアプリ開発を!