UWPでバイト配列を画像として表示する

画素ごとに値を指定して、画面に表示したいという状況は多いと思います。ここでは、UWPでバイト配列をつくり、画面にそのバイト配列を表示する方法を紹介します。

バイト配列を表示する

まず、ツールボックスより画面にImageとButtonを張りましょう。そして、それぞれの名前をimageMainとbuttonとします。次に、buttonをダブルクリックしてイベントをつくり、以下のようにボタンのイベントを定義します。

private async void button_Click(object sender, RoutedEventArgs e)
{
    int width = 256;
    int height = 256;
    byte[] data = new byte[width * height * 4];
    for (int i = 0; i < width; i++)
    {
        for (int j = 0; j < height; j++)
        {
            data[4 * (i + j * width)] = (byte)(i % 256);
            data[4 * (i + j * width) + 1] = (byte)(i % 256);
            data[4 * (i + j * width) + 2] = (byte)(i % 256);
            data[4 * (i + j * width) + 3] = (byte)(i % 256);
        }
    }
    WriteableBitmap bitmap = new WriteableBitmap(width, height);
    InMemoryRandomAccessStream inMRAS = new InMemoryRandomAccessStream();
    BitmapEncoder encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, inMRAS);
    encoder.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Ignore, (uint)bitmap.PixelWidth, (uint)bitmap.PixelHeight, 96.0, 96.0, data);
    await encoder.FlushAsync();
    BitmapImage bitmapImage = new BitmapImage();
    bitmapImage.SetSource(inMRAS);
    imageMain.Source = bitmapImage;
}

1行目の「async」を忘れないように。3-15行でバイト配列dataを定義しています。今回は幅256,高さ256でRGBAの画像なので、配列数は256 x 256 x 4となります。幅方向に徐々に色が明るくなるように「i%256」で画素の値を指定しています。

14行以降はバイト配列をimageMainに表示する操作をしています。

今の状態では、WritableBitmapやInMemoryRandomAccessStreamが認識できないので、MainPage.xaml.csの頭の部分に並ぶusingの下に、名前空間を以下のように導入します。

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

では、実行し、ボタンを押すと、グラデーションがimageMainに表示されます。

クリックイベントを追加する

画面をクリックされた際に、その位置情報を取りたい場合はimageMainのPointerPressedのイベントを追加します。そして、以下のようにコードを書くことで位置を取得できます。

private void imageMain_PointerPressed(object sender, PointerRoutedEventArgs e)
{
    var p = e.GetCurrentPoint(imageMain).Position;
    double posx = 255.0 * p.X / imageMain.ActualWidth;
    double posy = 255.0 * p.Y / imageMain.ActualHeight;
}

この際、左上が(0,0)となります。GetCurrentPointのPositionでimageMainの位置を取得できます。255でかけてActualWidthで割っているのは、幅や高さが256となっていないためです。

著者:安井 真人(やすい まさと)